map = new LinkedHashMap<>();
+
+ map.put("logger", new LoggingHandler(LogLevel.DEBUG));
+ map.put("protocol_splitter", new ProtocolSplitter());
+ map.put("protocol_decoder", new ProtocolDecoder(true));
+ map.put("protocol_encoder", new ProtocolEncoder());
+ map.put("handshake_handler", new HandshakeHandler(statusHandlerProvider));
+
+ return map;
+ }
+
+ @Provides
+ StatusHandler provideStatusHandler() {
+ return new StatusHandler();
}
}
diff --git a/src/main/java/mc/server/network/Server.java b/src/main/java/mc/server/network/Server.java
index f1464f8..b346a17 100644
--- a/src/main/java/mc/server/network/Server.java
+++ b/src/main/java/mc/server/network/Server.java
@@ -2,5 +2,5 @@ package mc.server.network;
public interface Server {
- void start(String host, int port);
+ void bind(String host, int port);
}
diff --git a/src/main/java/mc/server/network/netty/AbstractPacketHandler.java b/src/main/java/mc/server/network/netty/AbstractPacketHandler.java
new file mode 100644
index 0000000..733e255
--- /dev/null
+++ b/src/main/java/mc/server/network/netty/AbstractPacketHandler.java
@@ -0,0 +1,17 @@
+package mc.server.network.netty;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import mc.protocol.packets.Packet;
+
+public abstract class AbstractPacketHandler extends SimpleChannelInboundHandler {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, Packet msg) throws Exception {
+ channelRead1(ctx, (P) msg);
+ }
+
+ @SuppressWarnings("java:S112")
+ protected abstract void channelRead1(ChannelHandlerContext ctx, P packet) throws Exception;
+}
diff --git a/src/main/java/mc/server/network/netty/HandshakeHandler.java b/src/main/java/mc/server/network/netty/HandshakeHandler.java
new file mode 100644
index 0000000..8ceb9a1
--- /dev/null
+++ b/src/main/java/mc/server/network/netty/HandshakeHandler.java
@@ -0,0 +1,24 @@
+package mc.server.network.netty;
+
+import io.netty.channel.ChannelHandlerContext;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import mc.protocol.NetworkAttributes;
+import mc.protocol.packets.client.HandshakePacket;
+
+import javax.inject.Provider;
+
+@Slf4j
+@RequiredArgsConstructor
+public class HandshakeHandler extends AbstractPacketHandler {
+
+ private final Provider statusHandlerProvider;
+
+ @Override
+ protected void channelRead1(ChannelHandlerContext ctx, HandshakePacket packet) {
+ log.info("{}", packet);
+
+ ctx.channel().attr(NetworkAttributes.STATE).set(packet.getNextState());
+ ctx.pipeline().replace("handshake_handler", "status_handler", statusHandlerProvider.get());
+ }
+}
diff --git a/src/main/java/mc/server/network/netty/NettyServer.java b/src/main/java/mc/server/network/netty/NettyServer.java
index 4c3d19e..881914c 100644
--- a/src/main/java/mc/server/network/netty/NettyServer.java
+++ b/src/main/java/mc/server/network/netty/NettyServer.java
@@ -12,12 +12,11 @@ public class NettyServer implements Server {
private final ServerBootstrap serverBootstrap;
@Override
- public void start(String host, int port) {
+ public void bind(String host, int port) {
log.info("Network starting: {}:{}", host, port);
try {
- serverBootstrap.bind(host, port)
- .sync().channel().closeFuture().sync();
+ serverBootstrap.bind(host, port).sync().channel().closeFuture().sync();
} catch (InterruptedException e) {
if (log.isTraceEnabled()) {
log.trace("{}: {}", e.getClass().getSimpleName(), e.getMessage(), e);
diff --git a/src/main/java/mc/server/network/netty/StatusHandler.java b/src/main/java/mc/server/network/netty/StatusHandler.java
new file mode 100644
index 0000000..2d898ff
--- /dev/null
+++ b/src/main/java/mc/server/network/netty/StatusHandler.java
@@ -0,0 +1,33 @@
+package mc.server.network.netty;
+
+import io.netty.channel.ChannelHandlerContext;
+import lombok.extern.slf4j.Slf4j;
+import mc.protocol.packets.client.StatusServerRequest;
+import mc.protocol.packets.server.StatusServerResponse;
+
+@Slf4j
+public class StatusHandler extends AbstractPacketHandler {
+
+ @Override
+ protected void channelRead1(ChannelHandlerContext ctx, StatusServerRequest packet) {
+ log.info("{}", packet);
+
+ StatusServerResponse response = new StatusServerResponse();
+ response.setInfo("{\n" +
+ " \"version\": {\n" +
+ " \"name\": \"1.12.2\",\n" +
+ " \"protocol\": 340\n" +
+ " },\n" +
+ " \"players\": {\n" +
+ " \"max\": 0,\n" +
+ " \"online\": 0,\n" +
+ " \"sample\": []\n" +
+ " },\n" +
+ " \"description\": {\n" +
+ " \"text\": \"Hello world\"\n" +
+ " }\n" +
+ "}");
+
+ ctx.channel().writeAndFlush(response).channel().disconnect();
+ }
+}
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
index 9f1a1a5..192c634 100644
--- a/src/main/resources/logback.xml
+++ b/src/main/resources/logback.xml
@@ -4,11 +4,15 @@
- %d{HH:mm:ss.SSS} %-5level [%t] [%logger{36}] -- %msg%n
+ %d{HH:mm:ss.SSS} %-5level [%35.35logger{34}] -- %msg%n
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/mc/protocol/io/NetByteBufReadTest.java b/src/test/java/mc/protocol/io/NetByteBufReadTest.java
new file mode 100644
index 0000000..c48b6b4
--- /dev/null
+++ b/src/test/java/mc/protocol/io/NetByteBufReadTest.java
@@ -0,0 +1,307 @@
+package mc.protocol.io;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Random;
+import java.util.UUID;
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+
+class NetByteBufReadTest {
+
+ private static Random random;
+ private ByteArrayOutputStream baos;
+
+ @BeforeEach
+ void setUp() {
+ random = new Random(System.currentTimeMillis());
+ baos = new ByteArrayOutputStream();
+ }
+
+ @ParameterizedTest
+ @MethodSource("paramsReadBoolean")
+ void readBoolean(byte sourceByte, boolean expectedValue) {
+ baos.write(sourceByte);
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(expectedValue, netByteBuf.readBoolean());
+ }
+
+ @Test
+ void readByte() {
+ byte[] bytes = new byte[1];
+ random.nextBytes(bytes);
+ baos.write(bytes[0]);
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(bytes[0], netByteBuf.readByte());
+ }
+
+ @ParameterizedTest
+ @MethodSource("paramsReadUnsignedByte")
+ void readUnsignedByte(byte sourceByte, int expectedValue) {
+ baos.write(sourceByte);
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(expectedValue, netByteBuf.readUnsignedByte());
+ }
+
+ @Test
+ void readShort() throws IOException {
+ int value = Integer.valueOf(random.nextInt()).shortValue();
+ new DataOutputStream(baos).writeShort(value);
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(value, netByteBuf.readShort());
+ }
+
+ @Test
+ void readUnsignedShort() throws IOException {
+ int value = 32768;
+ new DataOutputStream(baos).writeShort(value);
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(value, netByteBuf.readUnsignedShort());
+ }
+
+ @ParameterizedTest
+ @MethodSource("paramsReadString")
+ void readString(String string) throws IOException {
+ final byte[] strBytes = string.getBytes(StandardCharsets.UTF_8);
+ final byte[] bytes = new byte[strBytes.length + 1];
+ bytes[0] = (byte) string.codePoints().count(); // допустим, что размер поместился в один байт
+ System.arraycopy(strBytes, 0, bytes, 1, strBytes.length);
+
+ baos.write(bytes);
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(string, netByteBuf.readString());
+ }
+
+ @Test
+ void readString_overSize() throws IOException {
+ String string = "123";
+ final byte[] strBytes = string.getBytes(StandardCharsets.UTF_8);
+ final byte[] bytes = new byte[strBytes.length + 1];
+ final int length = string.length();
+ bytes[0] = (byte) (length + 1); // допустим, что размер поместился в один байт
+ System.arraycopy(strBytes, 0, bytes, 1, strBytes.length);
+
+ baos.write(bytes);
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertThrows(DecoderException.class, () -> netByteBuf.readString(length));
+ }
+
+ @Test
+ void readString_lessZero() throws IOException {
+ String string = "123";
+ final byte[] strBytes = string.getBytes(StandardCharsets.UTF_8);
+ final byte[] bytes = new byte[strBytes.length + 5];
+ bytes[0] = (byte) 0xFF;
+ bytes[1] = (byte) 0xFF;
+ bytes[2] = (byte) 0xFF;
+ bytes[3] = (byte) 0xFF;
+ bytes[4] = (byte) 0x0F;
+ System.arraycopy(strBytes, 0, bytes, 5, strBytes.length);
+
+ baos.write(bytes);
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertThrows(DecoderException.class, () -> netByteBuf.readString(-1));
+ }
+
+ @ParameterizedTest
+ @MethodSource("paramsReadVarInt")
+ void readVarInt(byte[] sourceBytes, int expectedValue) throws IOException {
+ baos.write(sourceBytes);
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(expectedValue, netByteBuf.readVarInt());
+ }
+
+ @Test
+ void readVarInt_tooBig() throws IOException {
+ baos.write(new byte[]{ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x0F });
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(-1, netByteBuf.readVarInt());
+ }
+
+ @ParameterizedTest
+ @MethodSource({"paramsReadVarInt", "paramsReadVarLong"})
+ void readVarLong(byte[] sourceBytes, long expectedValue) throws IOException {
+ baos.write(sourceBytes);
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(expectedValue, netByteBuf.readVarLong());
+ }
+
+ @Test
+ void readVarLong_tooBig() throws IOException {
+ baos.write(new byte[]{ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0x0F });
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(-1, netByteBuf.readVarLong());
+ }
+
+ @Test
+ void readUUID() throws IOException {
+ final UUID uuid = UUID.randomUUID();
+ final long mostSignificantBits = uuid.getMostSignificantBits();
+ final long leastSignificantBits = uuid.getLeastSignificantBits();
+
+ baos.write(new byte[]{
+ (byte) ((mostSignificantBits >>> 56) & 0xFF),
+ (byte) ((mostSignificantBits >>> 48) & 0xFF),
+ (byte) ((mostSignificantBits >>> 40) & 0xFF),
+ (byte) ((mostSignificantBits >>> 32) & 0xFF),
+ (byte) ((mostSignificantBits >>> 24) & 0xFF),
+ (byte) ((mostSignificantBits >>> 16) & 0xFF),
+ (byte) ((mostSignificantBits >>> 8) & 0xFF),
+ (byte) (mostSignificantBits & 0xFF)
+ });
+ baos.write(new byte[]{
+ (byte) ((leastSignificantBits >>> 56) & 0xFF),
+ (byte) ((leastSignificantBits >>> 48) & 0xFF),
+ (byte) ((leastSignificantBits >>> 40) & 0xFF),
+ (byte) ((leastSignificantBits >>> 32) & 0xFF),
+ (byte) ((leastSignificantBits >>> 24) & 0xFF),
+ (byte) ((leastSignificantBits >>> 16) & 0xFF),
+ (byte) ((leastSignificantBits >>> 8) & 0xFF),
+ (byte) (leastSignificantBits & 0xFF)
+ });
+
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(uuid, netByteBuf.readUUID());
+ }
+
+ @Test
+ void readBytes() throws IOException {
+ byte[] bytes = new byte[128];
+ random.nextBytes(bytes);
+ baos.write(bytes);
+
+ byte[] actualBytes = new byte[128];
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+
+ assertEquals(bytes.length, netByteBuf.readableBytes());
+
+ netByteBuf.readBytes(actualBytes);
+
+ assertArrayEquals(bytes, actualBytes);
+ assertEquals(0, netByteBuf.readableBytes());
+ }
+
+ @Test
+ void read_offset() throws IOException {
+ byte[] bytes = new byte[128];
+ random.nextBytes(bytes);
+ baos.write(bytes);
+
+ byte[] buff = new byte[128];
+ NetByteBuf netByteBuf = new NetByteBuf(Unpooled.wrappedBuffer(baos.toByteArray()));
+ netByteBuf.readBytes(buff, 3, 11);
+
+ byte[] expectedBytes = new byte[11];
+ System.arraycopy(bytes, 0, expectedBytes, 0, 11);
+ byte[] actualBytes = new byte[11];
+ System.arraycopy(buff, 3, actualBytes, 0, 11);
+
+ assertArrayEquals(expectedBytes, actualBytes);
+ }
+
+ @SuppressWarnings("unused")
+ private static Stream paramsReadBoolean() {
+ return Stream.of(
+ Arguments.of((byte) 0x00, false),
+ Arguments.of((byte) 0x01, true)
+ );
+ }
+
+ @SuppressWarnings("unused")
+ private static Stream paramsReadUnsignedByte() {
+ return Stream.of(
+ Arguments.of((byte) 30, 30),
+ Arguments.of((byte) (0xFF & 130), 130)
+ );
+ }
+
+ @SuppressWarnings("unused")
+ private static Stream paramsReadString() {
+ return Stream.of(
+ Arguments.of(""),
+ Arguments.of("Latin"),
+ Arguments.of("Кириллица"),
+ Arguments.of("العربية"),
+ Arguments.of("ﬦﬣﬡ"), // Алфавитные формы представления
+ Arguments.of("\uD800\uDD07") // Эгейские цифры, [один]
+ );
+ }
+
+ @SuppressWarnings("unused")
+ private static Stream paramsReadVarInt() {
+ return Stream.of(
+ Arguments.of(new byte[]{ 0x78 }, 120),
+ Arguments.of(new byte[]{ (byte) 0xE0, 0x5D }, 12000),
+ Arguments.of(new byte[]{ (byte) 0xC0, (byte) 0xA9, 0x07 }, 120000),
+ Arguments.of(new byte[]{ (byte) 0x80, (byte) 0x9C, (byte) 0x9C, (byte) 0x39 }, 120_000_000),
+ Arguments.of(new byte[]{ (byte) 0x80, (byte) 0x98, (byte) 0x9A, (byte) 0xBC, 0x04 }, 1_200_000_000)
+ );
+ }
+
+ @SuppressWarnings("unused")
+ private static Stream paramsReadVarLong() {
+ return Stream.of(
+ Arguments.of(
+ new byte[]{ (byte) 0x80, (byte) 0xF0, (byte) 0x85, (byte) 0xDA, 0x2C },
+ 12_000_000_000L),
+ Arguments.of(
+ new byte[]{ (byte) 0x80, (byte) 0xE0, (byte) 0xBA, (byte) 0x84, (byte) 0xBF, 0x03 },
+ 120_000_000_000L),
+ Arguments.of(
+ new byte[]{ (byte) 0x80, (byte) 0x80, (byte) 0xF3, (byte) 0xBD, (byte) 0x9F, (byte) 0xDD,
+ 0x02 },
+ 12_000_000_000_000L),
+ Arguments.of(
+ new byte[]{ (byte) 0x80, (byte) 0x80, (byte) 0xEC, (byte) 0xAD, (byte) 0xCC, (byte) 0xEC,
+ (byte) 0x90, 0x02},
+ 1_200_000_000_000_000L),
+ Arguments.of(
+ new byte[]{ (byte) 0x80, (byte) 0x80, (byte) 0xB0, (byte) 0xE8, (byte) 0xD3, (byte) 0xEB,
+ (byte) 0x94, (byte) 0xD5, 0x01 },
+ 120_000_000_000_000_000L),
+ Arguments.of(
+ new byte[]{ (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+ (byte) 0x80, (byte) 0x80, (byte) 0x80, 0x01 },
+ Long.MIN_VALUE)
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/mc/protocol/io/NetByteBufWriteTest.java b/src/test/java/mc/protocol/io/NetByteBufWriteTest.java
new file mode 100644
index 0000000..74b6c5a
--- /dev/null
+++ b/src/test/java/mc/protocol/io/NetByteBufWriteTest.java
@@ -0,0 +1,246 @@
+package mc.protocol.io;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Random;
+import java.util.UUID;
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class NetByteBufWriteTest {
+
+ private static Random random;
+
+ @BeforeAll
+ static void setUp() {
+ random = new Random(System.currentTimeMillis());
+ }
+
+ @ParameterizedTest
+ @MethodSource("paramsWriteBoolean")
+ void writeBoolean(boolean sourceValue, byte expectedByte) {
+ ByteBuf byteBuf = Unpooled.buffer();
+ NetByteBuf netByteBuf = new NetByteBuf(byteBuf);
+
+ netByteBuf.writeBoolean(sourceValue);
+
+ assertEquals(expectedByte, byteBuf.array()[0]);
+ }
+
+ @ParameterizedTest
+ @MethodSource("paramsWriteByte")
+ void writeByte(byte sourceValue, byte expectedByte) {
+ ByteBuf byteBuf = Unpooled.buffer();
+ NetByteBuf netByteBuf = new NetByteBuf(byteBuf);
+
+ netByteBuf.writeByte(sourceValue);
+
+ assertEquals(expectedByte, byteBuf.array()[0]);
+ }
+
+ @ParameterizedTest
+ @MethodSource("paramsWriteString")
+ void writeString(String string) {
+ ByteBuf byteBuf = Unpooled.buffer();
+ NetByteBuf netByteBuf = new NetByteBuf(byteBuf);
+
+ netByteBuf.writeString(string);
+
+ byte[] actualArray = netByteBuf.copy(0, netByteBuf.readableBytes()).array();
+ int length = actualArray[0]; // допустим, что размер поместился в один байт
+ assertEquals(string.codePoints().count(), length);
+
+ byte[] dataBytes = new byte[actualArray.length - 1];
+ System.arraycopy(actualArray, 1, dataBytes, 0, dataBytes.length);
+ assertEquals(string, new String(dataBytes, StandardCharsets.UTF_8));
+ }
+
+ //возможно этот тест нужно перенести в NetByteBufReadTest
+ @Test
+ void writeString_overSize() {
+ String overSizeString = RandomStringUtils.randomAscii(Short.MAX_VALUE + Short.MAX_VALUE);
+
+ ByteBuf byteBuf = Unpooled.buffer();
+ NetByteBuf netByteBuf = new NetByteBuf(byteBuf);
+
+ netByteBuf.writeString(overSizeString);
+
+ NetByteBuf netByteBuf2 = new NetByteBuf(byteBuf.copy());
+ String actualString = netByteBuf2.readString();
+
+ String expectedString = overSizeString.substring(0, Short.MAX_VALUE);
+
+ assertEquals(expectedString, actualString);
+ }
+
+ @ParameterizedTest
+ @MethodSource("paramsWriteVarInt")
+ void writeVarInt(int sourceValue, byte[] expectedBytes) {
+ ByteBuf byteBuf = Unpooled.buffer();
+ NetByteBuf netByteBuf = new NetByteBuf(byteBuf);
+
+ netByteBuf.writeVarInt(sourceValue);
+ byte[] actualArray = netByteBuf.copy(0, netByteBuf.readableBytes()).array();
+
+ assertArrayEquals(expectedBytes, actualArray);
+ }
+
+ @ParameterizedTest
+ @MethodSource({ "paramsWriteVarInt", "paramsWriteVarLong" })
+ void writeVarLong(long sourceValue, byte[] expectedBytes) {
+ ByteBuf byteBuf = Unpooled.buffer();
+ NetByteBuf netByteBuf = new NetByteBuf(byteBuf);
+
+ netByteBuf.writeVarLong(sourceValue);
+ byte[] actualArray = netByteBuf.copy(0, netByteBuf.readableBytes()).array();
+
+ assertArrayEquals(expectedBytes, actualArray);
+ }
+
+ @Test
+ void writeUUID() {
+ final UUID uuid = UUID.randomUUID();
+
+ ByteBuf byteBuf = Unpooled.buffer();
+ NetByteBuf netByteBuf = new NetByteBuf(byteBuf);
+
+ netByteBuf.writeUUID(uuid);
+
+ final long mostSignificantBits = uuid.getMostSignificantBits();
+ final long leastSignificantBits = uuid.getLeastSignificantBits();
+
+ byte[] actualArray = netByteBuf.copy(0, netByteBuf.readableBytes()).array();
+
+ assertArrayEquals(new byte[]{
+ (byte) ((mostSignificantBits >>> 56) & 0xFF),
+ (byte) ((mostSignificantBits >>> 48) & 0xFF),
+ (byte) ((mostSignificantBits >>> 40) & 0xFF),
+ (byte) ((mostSignificantBits >>> 32) & 0xFF),
+ (byte) ((mostSignificantBits >>> 24) & 0xFF),
+ (byte) ((mostSignificantBits >>> 16) & 0xFF),
+ (byte) ((mostSignificantBits >>> 8) & 0xFF),
+ (byte) (mostSignificantBits & 0xFF),
+
+ (byte) ((leastSignificantBits >>> 56) & 0xFF),
+ (byte) ((leastSignificantBits >>> 48) & 0xFF),
+ (byte) ((leastSignificantBits >>> 40) & 0xFF),
+ (byte) ((leastSignificantBits >>> 32) & 0xFF),
+ (byte) ((leastSignificantBits >>> 24) & 0xFF),
+ (byte) ((leastSignificantBits >>> 16) & 0xFF),
+ (byte) ((leastSignificantBits >>> 8) & 0xFF),
+ (byte) (leastSignificantBits & 0xFF) },
+ actualArray);
+ }
+
+ @Test
+ void writeBytes() {
+ byte[] bytes = new byte[128];
+ random.nextBytes(bytes);
+
+ ByteBuf byteBuf = Unpooled.buffer();
+ NetByteBuf netByteBuf = new NetByteBuf(byteBuf);
+
+ netByteBuf.writeBytes(bytes);
+ byte[] actualArray = netByteBuf.copy(0, netByteBuf.readableBytes()).array();
+
+ assertArrayEquals(bytes, actualArray);
+ }
+
+ @Test
+ void write_offset() {
+ byte[] bytes = new byte[128];
+ random.nextBytes(bytes);
+
+ ByteBuf byteBuf = Unpooled.buffer();
+ NetByteBuf netByteBuf = new NetByteBuf(byteBuf);
+
+ netByteBuf.writeBytes(bytes, 3, 11);
+
+ byte[] actualBytes = new byte[11];
+ System.arraycopy(byteBuf.array(), 0, actualBytes, 0, 11);
+
+ byte[] expectedBytes = new byte[11];
+ System.arraycopy(bytes, 3, expectedBytes, 0, 11);
+
+ assertArrayEquals(expectedBytes, actualBytes);
+ }
+
+ @SuppressWarnings("unused")
+ private static Stream paramsWriteBoolean() {
+ return Stream.of(
+ Arguments.of(false, (byte) 0x00),
+ Arguments.of(true, (byte) 0x01)
+ );
+ }
+
+ @SuppressWarnings("unused")
+ private static Stream paramsWriteByte() {
+ byte b = Integer.valueOf(random.nextInt()).byteValue();
+
+ return Stream.of(
+ Arguments.of(b, b),
+ Arguments.of((byte) 128, (byte) -128)
+ );
+ }
+
+ @SuppressWarnings("unused")
+ private static Stream paramsWriteString() {
+ return Stream.of(
+ Arguments.of(""),
+ Arguments.of("Latin"),
+ Arguments.of("Кириллица"),
+ Arguments.of("العربية"),
+ Arguments.of("ﬦﬣﬡ"), // Алфавитные формы представления
+ Arguments.of("\uD800\uDD07") // Эгейские цифры, [один]
+ );
+ }
+
+ @SuppressWarnings("unused")
+ private static Stream paramsWriteVarInt() {
+ return Stream.of(
+ Arguments.of(120, new byte[]{ 0x78 }),
+ Arguments.of(12000, new byte[]{ (byte) 0xE0, 0x5D }),
+ Arguments.of(120000, new byte[]{ (byte) 0xC0, (byte) 0xA9, 0x07 }),
+ Arguments.of(120000000, new byte[]{ (byte) 0x80, (byte) 0x9C, (byte) 0x9C, (byte) 0x39 }),
+ Arguments.of(1200000000, new byte[]{ (byte) 0x80, (byte) 0x98, (byte) 0x9A, (byte) 0xBC, 0x04 })
+ );
+ }
+
+ @SuppressWarnings("unused")
+ private static Stream paramsWriteVarLong() {
+ return Stream.of(
+ Arguments.of(
+ 12_000_000_000L,
+ new byte[]{ (byte) 0x80, (byte) 0xF0, (byte) 0x85, (byte) 0xDA, 0x2C }),
+ Arguments.of(
+ 120_000_000_000L,
+ new byte[]{ (byte) 0x80, (byte) 0xE0, (byte) 0xBA, (byte) 0x84, (byte) 0xBF, 0x03 }),
+ Arguments.of(
+ 12_000_000_000_000L,
+ new byte[]{ (byte) 0x80, (byte) 0x80, (byte) 0xF3, (byte) 0xBD, (byte) 0x9F, (byte) 0xDD,
+ 0x02 }),
+ Arguments.of(
+ 1_200_000_000_000_000L,
+ new byte[]{ (byte) 0x80, (byte) 0x80, (byte) 0xEC, (byte) 0xAD, (byte) 0xCC, (byte) 0xEC,
+ (byte) 0x90, 0x02 }),
+ Arguments.of(
+ 120_000_000_000_000_000L,
+ new byte[]{ (byte) 0x80, (byte) 0x80, (byte) 0xB0, (byte) 0xE8, (byte) 0xD3, (byte) 0xEB,
+ (byte) 0x94, (byte) 0xD5, 0x01 }),
+ Arguments.of(
+ Long.MIN_VALUE,
+ new byte[]{ (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+ (byte) 0x80, (byte) 0x80, (byte) 0x80, 0x01 })
+ );
+ }
+}
From fdc975d268ecdbe373e9de0e82f122f6d340eb0a Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Mon, 26 Apr 2021 00:41:56 +0300
Subject: [PATCH 03/34] =?UTF-8?q?=D0=B7=D0=B0=D0=BF=D1=80=D0=B5=D1=82=20?=
=?UTF-8?q?=D0=B2=D1=85=D0=BE=D0=B4=D0=B0=20=D0=BD=D0=B0=20=D1=81=D0=B5?=
=?UTF-8?q?=D1=80=D0=B2=D0=B5=D1=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/main/java/mc/protocol/State.java | 8 ++++
.../packets/client/LoginStartPacket.java | 43 +++++++++++++++++
.../packets/server/DisconnectPacket.java | 47 +++++++++++++++++++
src/main/java/mc/server/di/NetworkModule.java | 17 +++++--
.../{ => handler}/AbstractPacketHandler.java | 2 +-
.../netty/{ => handler}/HandshakeHandler.java | 11 ++++-
.../network/netty/handler/LoginHandler.java | 18 +++++++
.../netty/{ => handler}/StatusHandler.java | 2 +-
8 files changed, 140 insertions(+), 8 deletions(-)
create mode 100644 src/main/java/mc/protocol/packets/client/LoginStartPacket.java
create mode 100644 src/main/java/mc/protocol/packets/server/DisconnectPacket.java
rename src/main/java/mc/server/network/netty/{ => handler}/AbstractPacketHandler.java (92%)
rename src/main/java/mc/server/network/netty/{ => handler}/HandshakeHandler.java (58%)
create mode 100644 src/main/java/mc/server/network/netty/handler/LoginHandler.java
rename src/main/java/mc/server/network/netty/{ => handler}/StatusHandler.java (95%)
diff --git a/src/main/java/mc/protocol/State.java b/src/main/java/mc/protocol/State.java
index da448e6..3d38333 100644
--- a/src/main/java/mc/protocol/State.java
+++ b/src/main/java/mc/protocol/State.java
@@ -7,7 +7,9 @@ import lombok.RequiredArgsConstructor;
import mc.protocol.packets.Packet;
import mc.protocol.packets.PacketDirection;
import mc.protocol.packets.client.HandshakePacket;
+import mc.protocol.packets.client.LoginStartPacket;
import mc.protocol.packets.client.StatusServerRequest;
+import mc.protocol.packets.server.DisconnectPacket;
import mc.protocol.packets.server.StatusServerResponse;
import javax.annotation.Nullable;
@@ -24,6 +26,12 @@ public enum State {
ImmutableBiMap.of(0x00, StatusServerRequest.class),
// client bound
ImmutableBiMap.of(0x00, StatusServerResponse.class)
+ ),
+ LOGIN(2,
+ // server bound
+ ImmutableBiMap.of(0x00, LoginStartPacket.class),
+ // client bound
+ ImmutableBiMap.of(0x00, DisconnectPacket.class)
);
@Nullable
diff --git a/src/main/java/mc/protocol/packets/client/LoginStartPacket.java b/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
new file mode 100644
index 0000000..6fa953e
--- /dev/null
+++ b/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
@@ -0,0 +1,43 @@
+package mc.protocol.packets.client;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import mc.protocol.State;
+import mc.protocol.io.NetByteBuf;
+import mc.protocol.packets.Packet;
+
+/**
+ * Login start packet.
+ *
+ * Начало авторизации.
+ *
+ * Структура пакета
+ *
+ * | FIELD | TYPE | NOTES |
+ * |-------|--------|------------------|
+ * | Name | String | Имя/Логин игрока |
+ *
+ *
+ * @see Login start
+ * @see State
+ */
+@NoArgsConstructor
+@Getter
+@EqualsAndHashCode
+@ToString
+public class LoginStartPacket implements Packet {
+
+ private String name;
+
+ @Override
+ public void readSelf(NetByteBuf netByteBuf) {
+ this.name = netByteBuf.readString();
+ }
+
+ @Override
+ public void writeSelf(NetByteBuf netByteBuf) {
+ netByteBuf.writeString(name);
+ }
+}
diff --git a/src/main/java/mc/protocol/packets/server/DisconnectPacket.java b/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
new file mode 100644
index 0000000..2cfb3e2
--- /dev/null
+++ b/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
@@ -0,0 +1,47 @@
+package mc.protocol.packets.server;
+
+import lombok.Data;
+import mc.protocol.State;
+import mc.protocol.io.NetByteBuf;
+import mc.protocol.packets.Packet;
+
+/**
+ * Diconnect packet.
+ *
+ * Отключение клиента сервером с указанием причины.
+ *
+ * Структура пакета
+ *
+ * | FIELD | TYPE | NOTES |
+ * |--------|------|----------------------------------|
+ * | Reason | Text | Причина отключения. Опционально. |
+ *
+ *
+ * @see Disconnect
+ * @see State
+ */
+@Data
+public class DisconnectPacket implements Packet {
+
+ /**
+ * Причина отключения.
+ *
+ * Пример:
+ *
+ * {
+ * "text": "foo"
+ * }
+ *
+ */
+ private String reason;
+
+ @Override
+ public void readSelf(NetByteBuf netByteBuf) {
+ this.reason = netByteBuf.readString();
+ }
+
+ @Override
+ public void writeSelf(NetByteBuf netByteBuf) {
+ netByteBuf.writeString(reason);
+ }
+}
diff --git a/src/main/java/mc/server/di/NetworkModule.java b/src/main/java/mc/server/di/NetworkModule.java
index c06bb2c..c5ca566 100644
--- a/src/main/java/mc/server/di/NetworkModule.java
+++ b/src/main/java/mc/server/di/NetworkModule.java
@@ -16,9 +16,10 @@ import mc.protocol.io.codec.ProtocolDecoder;
import mc.protocol.io.codec.ProtocolEncoder;
import mc.protocol.io.codec.ProtocolSplitter;
import mc.server.network.Server;
-import mc.server.network.netty.HandshakeHandler;
+import mc.server.network.netty.handler.HandshakeHandler;
import mc.server.network.netty.NettyServer;
-import mc.server.network.netty.StatusHandler;
+import mc.server.network.netty.handler.LoginHandler;
+import mc.server.network.netty.handler.StatusHandler;
import javax.inject.Provider;
import java.util.LinkedHashMap;
@@ -56,14 +57,17 @@ public class NetworkModule {
}
@Provides
- Map provideChannelHandlerMap(Provider statusHandlerProvider) {
+ Map provideChannelHandlerMap(
+ Provider statusHandlerProvider,
+ Provider loginHandlerProvider
+ ) {
Map map = new LinkedHashMap<>();
map.put("logger", new LoggingHandler(LogLevel.DEBUG));
map.put("protocol_splitter", new ProtocolSplitter());
map.put("protocol_decoder", new ProtocolDecoder(true));
map.put("protocol_encoder", new ProtocolEncoder());
- map.put("handshake_handler", new HandshakeHandler(statusHandlerProvider));
+ map.put("handshake_handler", new HandshakeHandler(statusHandlerProvider, loginHandlerProvider));
return map;
}
@@ -72,4 +76,9 @@ public class NetworkModule {
StatusHandler provideStatusHandler() {
return new StatusHandler();
}
+
+ @Provides
+ LoginHandler provideLoginHandler() {
+ return new LoginHandler();
+ }
}
diff --git a/src/main/java/mc/server/network/netty/AbstractPacketHandler.java b/src/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java
similarity index 92%
rename from src/main/java/mc/server/network/netty/AbstractPacketHandler.java
rename to src/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java
index 733e255..3d2d900 100644
--- a/src/main/java/mc/server/network/netty/AbstractPacketHandler.java
+++ b/src/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java
@@ -1,4 +1,4 @@
-package mc.server.network.netty;
+package mc.server.network.netty.handler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
diff --git a/src/main/java/mc/server/network/netty/HandshakeHandler.java b/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
similarity index 58%
rename from src/main/java/mc/server/network/netty/HandshakeHandler.java
rename to src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
index 8ceb9a1..5f31d3e 100644
--- a/src/main/java/mc/server/network/netty/HandshakeHandler.java
+++ b/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
@@ -1,9 +1,10 @@
-package mc.server.network.netty;
+package mc.server.network.netty.handler;
import io.netty.channel.ChannelHandlerContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import mc.protocol.NetworkAttributes;
+import mc.protocol.State;
import mc.protocol.packets.client.HandshakePacket;
import javax.inject.Provider;
@@ -13,12 +14,18 @@ import javax.inject.Provider;
public class HandshakeHandler extends AbstractPacketHandler {
private final Provider statusHandlerProvider;
+ private final Provider loginHandlerProvider;
@Override
protected void channelRead1(ChannelHandlerContext ctx, HandshakePacket packet) {
log.info("{}", packet);
ctx.channel().attr(NetworkAttributes.STATE).set(packet.getNextState());
- ctx.pipeline().replace("handshake_handler", "status_handler", statusHandlerProvider.get());
+
+ if (State.STATUS == packet.getNextState()) {
+ ctx.pipeline().replace("handshake_handler", "status_handler", statusHandlerProvider.get());
+ } else if (State.LOGIN == packet.getNextState()) {
+ ctx.channel().pipeline().replace("handshake_handler", "login_handler", loginHandlerProvider.get());
+ }
}
}
diff --git a/src/main/java/mc/server/network/netty/handler/LoginHandler.java b/src/main/java/mc/server/network/netty/handler/LoginHandler.java
new file mode 100644
index 0000000..8a0d92c
--- /dev/null
+++ b/src/main/java/mc/server/network/netty/handler/LoginHandler.java
@@ -0,0 +1,18 @@
+package mc.server.network.netty.handler;
+
+import io.netty.channel.ChannelHandlerContext;
+import mc.protocol.packets.client.LoginStartPacket;
+import mc.protocol.packets.server.DisconnectPacket;
+
+public class LoginHandler extends AbstractPacketHandler {
+
+ @Override
+ protected void channelRead1(ChannelHandlerContext ctx, LoginStartPacket packet) {
+ DisconnectPacket disconnectPacket = new DisconnectPacket();
+ disconnectPacket.setReason("{\n" +
+ " \"text\": \"Server is not available.\"\n" +
+ "}");
+
+ ctx.channel().writeAndFlush(disconnectPacket).channel().disconnect();
+ }
+}
diff --git a/src/main/java/mc/server/network/netty/StatusHandler.java b/src/main/java/mc/server/network/netty/handler/StatusHandler.java
similarity index 95%
rename from src/main/java/mc/server/network/netty/StatusHandler.java
rename to src/main/java/mc/server/network/netty/handler/StatusHandler.java
index 2d898ff..0628875 100644
--- a/src/main/java/mc/server/network/netty/StatusHandler.java
+++ b/src/main/java/mc/server/network/netty/handler/StatusHandler.java
@@ -1,4 +1,4 @@
-package mc.server.network.netty;
+package mc.server.network.netty.handler;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
From 39b858696f37e5db31fc5c76297d3bc835f8e1ba Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Mon, 26 Apr 2021 14:00:19 +0300
Subject: [PATCH 04/34] =?UTF-8?q?=D1=83=D0=B1=D0=B8=D1=80=D0=B0=D0=B5?=
=?UTF-8?q?=D0=BC=20LogicPlugin?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
build.gradle | 20 +++++++++++++++++--
.../gradle/extention/LogicExtention.java | 19 ------------------
.../dmitriymx/gradle/plugin/LogicPlugin.java | 13 ------------
3 files changed, 18 insertions(+), 34 deletions(-)
delete mode 100644 buildSrc/src/main/java/ru/dmitriymx/gradle/extention/LogicExtention.java
delete mode 100644 buildSrc/src/main/java/ru/dmitriymx/gradle/plugin/LogicPlugin.java
diff --git a/build.gradle b/build.gradle
index 7de1955..9598373 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,7 +4,22 @@
*/
import ru.dmitriymx.gradle.plugin.LibsPlugin
-import ru.dmitriymx.gradle.plugin.LogicPlugin
+
+class Logic {
+ private final Project project
+
+ Logic(Project project) {
+ this.project = project
+ }
+
+ String getProperty1(String propertyName1, String propertyName2) {
+ return (String) (project.hasProperty(propertyName1) ? project.property(propertyName1) : project.property(propertyName2))
+ }
+
+ String getProperty1(String propertyName) {
+ return (String) (project.hasProperty(propertyName) ? project.property(propertyName) : null)
+ }
+}
plugins {
id 'java'
@@ -12,7 +27,8 @@ plugins {
}
apply plugin: LibsPlugin
-apply plugin: LogicPlugin
+
+def logic = new Logic(project)
project.group = logic.getProperty1('project.group')
project.version = logic.getProperty1('project.version')
diff --git a/buildSrc/src/main/java/ru/dmitriymx/gradle/extention/LogicExtention.java b/buildSrc/src/main/java/ru/dmitriymx/gradle/extention/LogicExtention.java
deleted file mode 100644
index c596a13..0000000
--- a/buildSrc/src/main/java/ru/dmitriymx/gradle/extention/LogicExtention.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package ru.dmitriymx.gradle.extention;
-
-import org.gradle.api.Project;
-
-public class LogicExtention {
- private final Project project;
-
- public LogicExtention(Project project) {
- this.project = project;
- }
-
- public String getProperty1(String propertyName1, String propertyName2) {
- return (String) (project.hasProperty(propertyName1) ? project.property(propertyName1) : project.property(propertyName2));
- }
-
- public String getProperty1(String propertyName) {
- return (String) (project.hasProperty(propertyName) ? project.property(propertyName) : null);
- }
-}
diff --git a/buildSrc/src/main/java/ru/dmitriymx/gradle/plugin/LogicPlugin.java b/buildSrc/src/main/java/ru/dmitriymx/gradle/plugin/LogicPlugin.java
deleted file mode 100644
index 4068cf4..0000000
--- a/buildSrc/src/main/java/ru/dmitriymx/gradle/plugin/LogicPlugin.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package ru.dmitriymx.gradle.plugin;
-
-import org.gradle.api.Plugin;
-import org.gradle.api.Project;
-import ru.dmitriymx.gradle.extention.LogicExtention;
-
-public class LogicPlugin implements Plugin {
-
- @Override
- public void apply(Project project) {
- project.getExtensions().create("logic", LogicExtention.class, project);
- }
-}
From 612eef236172a5d0addd54aaafefa7b6bf227b56 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Mon, 26 Apr 2021 14:34:58 +0300
Subject: [PATCH 05/34] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=BE?=
=?UTF-8?q?=D1=81=20=D1=82=D0=B8=D0=BF=D0=B8=D1=87=D0=BD=D1=8B=D1=85=20?=
=?UTF-8?q?=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BA=20=D0=B2=20log?=
=?UTF-8?q?ic.gradle?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
build.gradle | 33 +--------------------------------
logic.gradle | 17 +++++++++++++++++
2 files changed, 18 insertions(+), 32 deletions(-)
create mode 100644 logic.gradle
diff --git a/build.gradle b/build.gradle
index 9598373..bce7640 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,44 +5,13 @@
import ru.dmitriymx.gradle.plugin.LibsPlugin
-class Logic {
- private final Project project
-
- Logic(Project project) {
- this.project = project
- }
-
- String getProperty1(String propertyName1, String propertyName2) {
- return (String) (project.hasProperty(propertyName1) ? project.property(propertyName1) : project.property(propertyName2))
- }
-
- String getProperty1(String propertyName) {
- return (String) (project.hasProperty(propertyName) ? project.property(propertyName) : null)
- }
-}
-
plugins {
id 'java'
id 'application'
}
apply plugin: LibsPlugin
-
-def logic = new Logic(project)
-
-project.group = logic.getProperty1('project.group')
-project.version = logic.getProperty1('project.version')
-jar.archiveBaseName.set(logic.getProperty1('project.name'))
-
-compileJava {
- sourceCompatibility = targetCompatibility = JavaVersion.VERSION_11
- options.encoding = 'UTF-8'
-}
-
-repositories {
- mavenLocal()
- mavenCentral()
-}
+apply from: rootDir.toPath().resolve('logic.gradle').toFile()
dependencies {
annotationProcessor libs.lombok
diff --git a/logic.gradle b/logic.gradle
new file mode 100644
index 0000000..0e9a252
--- /dev/null
+++ b/logic.gradle
@@ -0,0 +1,17 @@
+String getProperty1(String propertyName1, String propertyName2) {
+ return (String) (project.hasProperty(propertyName1) ? project.property(propertyName1) : project.property(propertyName2))
+}
+
+project.group = getProperty1('module.group', 'project.group')
+project.version = getProperty1('module.version', 'project.version')
+project.jar.archiveBaseName.set(getProperty1('module.name', 'project.name'))
+
+compileJava {
+ sourceCompatibility = targetCompatibility = JavaVersion.VERSION_11
+ options.encoding = 'UTF-8'
+}
+
+repositories {
+ mavenLocal()
+ mavenCentral()
+}
\ No newline at end of file
From a8f567ad2cff38e78ecc088c64999ecf84dc1ec9 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Mon, 26 Apr 2021 14:47:16 +0300
Subject: [PATCH 06/34] =?UTF-8?q?=D1=83=D0=B1=D0=B8=D1=80=D0=B0=D0=B5?=
=?UTF-8?q?=D0=BC=20LibsPlugin?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
build.gradle | 36 +++++++++++++--
.../gradle/extention/LibsExtention.java | 46 -------------------
.../dmitriymx/gradle/plugin/LibsPlugin.java | 13 ------
3 files changed, 33 insertions(+), 62 deletions(-)
delete mode 100644 buildSrc/src/main/java/ru/dmitriymx/gradle/extention/LibsExtention.java
delete mode 100644 buildSrc/src/main/java/ru/dmitriymx/gradle/plugin/LibsPlugin.java
diff --git a/build.gradle b/build.gradle
index bce7640..fd18383 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,16 +3,46 @@
gradle run
*/
-import ru.dmitriymx.gradle.plugin.LibsPlugin
-
plugins {
id 'java'
id 'application'
}
-apply plugin: LibsPlugin
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
+ext {
+ slf4j_version = '1.7.30'
+ logback_version = '1.2.3'
+ dagger2_version = '2.33'
+ junit_version = '5.5.2'
+
+ libs = [
+ lombok : 'org.projectlombok:lombok:1.18.12',
+ annotations: 'com.google.code.findbugs:jsr305:3.0.2',
+ guava : 'com.google.guava:guava:30.1-jre',
+ lang3 : 'org.apache.commons:commons-lang3:3.11',
+ ]
+
+ libs.logger = [
+ slf4j : ["org.slf4j:slf4j-api:${slf4j_version}",
+ "org.slf4j:jcl-over-slf4j:${slf4j_version}"],
+ logback: ["ch.qos.logback:logback-core:${logback_version}",
+ "ch.qos.logback:logback-classic:${logback_version}"]
+ ]
+
+ libs.dagger2 = [
+ implementation: "com.google.dagger:dagger:${dagger2_version}",
+ annotationProcessor: "com.google.dagger:dagger-compiler:${dagger2_version}"
+ ]
+
+ libs.junit5 = [
+ api: "org.junit.jupiter:junit-jupiter-api:${junit_version}",
+ //runtime only
+ engine: "org.junit.jupiter:junit-jupiter-engine:${junit_version}",
+ params: "org.junit.jupiter:junit-jupiter-params:${junit_version}"
+ ]
+}
+
dependencies {
annotationProcessor libs.lombok
compileOnly libs.lombok
diff --git a/buildSrc/src/main/java/ru/dmitriymx/gradle/extention/LibsExtention.java b/buildSrc/src/main/java/ru/dmitriymx/gradle/extention/LibsExtention.java
deleted file mode 100644
index 05123ee..0000000
--- a/buildSrc/src/main/java/ru/dmitriymx/gradle/extention/LibsExtention.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package ru.dmitriymx.gradle.extention;
-
-import java.util.List;
-
-public class LibsExtention {
-
- public final String lombok = "org.projectlombok:lombok:1.18.12";
- public final String annotations = "com.google.code.findbugs:jsr305:3.0.2";
- public final String guava = "com.google.guava:guava:30.1-jre";
- public final String lang3 = "org.apache.commons:commons-lang3:3.11";
-
- public final LoggerLibs logger = new LoggerLibs();
- public final Dagger2Libs dagger2 = new Dagger2Libs();
- public final Junit5Libs junit5 = new Junit5Libs();
-
- public static final class LoggerLibs {
- private final String slf4j_version = "1.7.30";
- private final String logback_version = "1.2.3";
-
- public final List slf4j = List.of(
- "org.slf4j:slf4j-api:" + slf4j_version,
- "org.slf4j:jcl-over-slf4j:" + slf4j_version
- );
-
- public final List logback = List.of(
- "ch.qos.logback:logback-core:" + logback_version,
- "ch.qos.logback:logback-classic:" + logback_version
- );
- }
-
- public static final class Dagger2Libs {
- private final String dagger2_version = "2.33";
-
- public final String implementation = "com.google.dagger:dagger:" + dagger2_version;
- public final String annotationProcessor = "com.google.dagger:dagger-compiler:" + dagger2_version;
- }
-
- public static final class Junit5Libs {
- private final String junit_version = "5.5.2";
-
- public final String api = "org.junit.jupiter:junit-jupiter-api:" + junit_version;
- /** runtimeOnly */
- public final String engine = "org.junit.jupiter:junit-jupiter-engine:" + junit_version;
- public final String params = "org.junit.jupiter:junit-jupiter-params:" + junit_version;
- }
-}
diff --git a/buildSrc/src/main/java/ru/dmitriymx/gradle/plugin/LibsPlugin.java b/buildSrc/src/main/java/ru/dmitriymx/gradle/plugin/LibsPlugin.java
deleted file mode 100644
index 243fa5d..0000000
--- a/buildSrc/src/main/java/ru/dmitriymx/gradle/plugin/LibsPlugin.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package ru.dmitriymx.gradle.plugin;
-
-import org.gradle.api.Plugin;
-import org.gradle.api.Project;
-import ru.dmitriymx.gradle.extention.LibsExtention;
-
-public class LibsPlugin implements Plugin {
-
- @Override
- public void apply(Project project) {
- project.getExtensions().create("libs", LibsExtention.class);
- }
-}
From 65a2f4ef817dead73e1cd14264eeeb023c2b8cc4 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Mon, 26 Apr 2021 14:51:21 +0300
Subject: [PATCH 07/34] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=BE?=
=?UTF-8?q?=D1=81=20=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5=D0=BA?=
=?UTF-8?q?=20=D0=B2=20libs.gradle?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
build.gradle | 34 +---------------------------------
libs.gradle | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+), 33 deletions(-)
create mode 100644 libs.gradle
diff --git a/build.gradle b/build.gradle
index fd18383..3180acf 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,39 +9,7 @@ plugins {
}
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
-
-ext {
- slf4j_version = '1.7.30'
- logback_version = '1.2.3'
- dagger2_version = '2.33'
- junit_version = '5.5.2'
-
- libs = [
- lombok : 'org.projectlombok:lombok:1.18.12',
- annotations: 'com.google.code.findbugs:jsr305:3.0.2',
- guava : 'com.google.guava:guava:30.1-jre',
- lang3 : 'org.apache.commons:commons-lang3:3.11',
- ]
-
- libs.logger = [
- slf4j : ["org.slf4j:slf4j-api:${slf4j_version}",
- "org.slf4j:jcl-over-slf4j:${slf4j_version}"],
- logback: ["ch.qos.logback:logback-core:${logback_version}",
- "ch.qos.logback:logback-classic:${logback_version}"]
- ]
-
- libs.dagger2 = [
- implementation: "com.google.dagger:dagger:${dagger2_version}",
- annotationProcessor: "com.google.dagger:dagger-compiler:${dagger2_version}"
- ]
-
- libs.junit5 = [
- api: "org.junit.jupiter:junit-jupiter-api:${junit_version}",
- //runtime only
- engine: "org.junit.jupiter:junit-jupiter-engine:${junit_version}",
- params: "org.junit.jupiter:junit-jupiter-params:${junit_version}"
- ]
-}
+apply from: rootDir.toPath().resolve('libs.gradle').toFile()
dependencies {
annotationProcessor libs.lombok
diff --git a/libs.gradle b/libs.gradle
new file mode 100644
index 0000000..600bd97
--- /dev/null
+++ b/libs.gradle
@@ -0,0 +1,35 @@
+//file:noinspection GroovyAssignabilityCheck
+//file:noinspection GrUnresolvedAccess
+
+def slf4j_version = '1.7.30'
+def logback_version = '1.2.3'
+def dagger2_version = '2.33'
+def junit_version = '5.5.2'
+
+ext {
+ libs = [
+ lombok : 'org.projectlombok:lombok:1.18.12',
+ annotations: 'com.google.code.findbugs:jsr305:3.0.2',
+ guava : 'com.google.guava:guava:30.1-jre',
+ lang3 : 'org.apache.commons:commons-lang3:3.11',
+ ]
+
+ libs.logger = [
+ slf4j : ["org.slf4j:slf4j-api:${slf4j_version}",
+ "org.slf4j:jcl-over-slf4j:${slf4j_version}"],
+ logback: ["ch.qos.logback:logback-core:${logback_version}",
+ "ch.qos.logback:logback-classic:${logback_version}"]
+ ]
+
+ libs.dagger2 = [
+ implementation : "com.google.dagger:dagger:${dagger2_version}",
+ annotationProcessor: "com.google.dagger:dagger-compiler:${dagger2_version}"
+ ]
+
+ libs.junit5 = [
+ api : "org.junit.jupiter:junit-jupiter-api:${junit_version}",
+ //runtime only
+ engine: "org.junit.jupiter:junit-jupiter-engine:${junit_version}",
+ params: "org.junit.jupiter:junit-jupiter-params:${junit_version}"
+ ]
+}
\ No newline at end of file
From 38091e8685320ec64549f8ec4c0d951bdc7c0560 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Mon, 26 Apr 2021 15:02:54 +0300
Subject: [PATCH 08/34] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=BE?=
=?UTF-8?q?=D1=81=20=D0=BA=D0=BE=D0=B4=D0=B0=20=D0=B2=20=D0=BF=D0=BE=D0=B4?=
=?UTF-8?q?=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
logic.gradle | 2 ++
build.gradle => server/build.gradle | 7 ++-----
server/gradle.properties | 3 +++
.../src}/main/java/mc/protocol/NetworkAttributes.java | 0
{src => server/src}/main/java/mc/protocol/State.java | 0
.../src}/main/java/mc/protocol/io/DecoderException.java | 0
.../src}/main/java/mc/protocol/io/NetByteBuf.java | 0
.../main/java/mc/protocol/io/codec/ProtocolDecoder.java | 0
.../main/java/mc/protocol/io/codec/ProtocolEncoder.java | 0
.../main/java/mc/protocol/io/codec/ProtocolSplitter.java | 0
.../src}/main/java/mc/protocol/packets/EmptyPacket.java | 0
.../src}/main/java/mc/protocol/packets/Packet.java | 0
.../main/java/mc/protocol/packets/PacketDirection.java | 0
.../src}/main/java/mc/protocol/packets/UnknownPacket.java | 0
.../java/mc/protocol/packets/client/HandshakePacket.java | 0
.../java/mc/protocol/packets/client/LoginStartPacket.java | 0
.../mc/protocol/packets/client/StatusServerRequest.java | 0
.../java/mc/protocol/packets/server/DisconnectPacket.java | 0
.../mc/protocol/packets/server/StatusServerResponse.java | 0
{src => server/src}/main/java/mc/server/Main.java | 0
.../src}/main/java/mc/server/di/NetworkComponent.java | 0
.../src}/main/java/mc/server/di/NetworkModule.java | 0
.../src}/main/java/mc/server/network/Server.java | 0
.../main/java/mc/server/network/netty/NettyServer.java | 0
.../network/netty/handler/AbstractPacketHandler.java | 0
.../mc/server/network/netty/handler/HandshakeHandler.java | 0
.../java/mc/server/network/netty/handler/LoginHandler.java | 0
.../mc/server/network/netty/handler/StatusHandler.java | 0
{src => server/src}/main/resources/logback.xml | 0
.../src}/test/java/mc/protocol/io/NetByteBufReadTest.java | 0
.../src}/test/java/mc/protocol/io/NetByteBufWriteTest.java | 0
31 files changed, 7 insertions(+), 5 deletions(-)
rename build.gradle => server/build.gradle (95%)
create mode 100644 server/gradle.properties
rename {src => server/src}/main/java/mc/protocol/NetworkAttributes.java (100%)
rename {src => server/src}/main/java/mc/protocol/State.java (100%)
rename {src => server/src}/main/java/mc/protocol/io/DecoderException.java (100%)
rename {src => server/src}/main/java/mc/protocol/io/NetByteBuf.java (100%)
rename {src => server/src}/main/java/mc/protocol/io/codec/ProtocolDecoder.java (100%)
rename {src => server/src}/main/java/mc/protocol/io/codec/ProtocolEncoder.java (100%)
rename {src => server/src}/main/java/mc/protocol/io/codec/ProtocolSplitter.java (100%)
rename {src => server/src}/main/java/mc/protocol/packets/EmptyPacket.java (100%)
rename {src => server/src}/main/java/mc/protocol/packets/Packet.java (100%)
rename {src => server/src}/main/java/mc/protocol/packets/PacketDirection.java (100%)
rename {src => server/src}/main/java/mc/protocol/packets/UnknownPacket.java (100%)
rename {src => server/src}/main/java/mc/protocol/packets/client/HandshakePacket.java (100%)
rename {src => server/src}/main/java/mc/protocol/packets/client/LoginStartPacket.java (100%)
rename {src => server/src}/main/java/mc/protocol/packets/client/StatusServerRequest.java (100%)
rename {src => server/src}/main/java/mc/protocol/packets/server/DisconnectPacket.java (100%)
rename {src => server/src}/main/java/mc/protocol/packets/server/StatusServerResponse.java (100%)
rename {src => server/src}/main/java/mc/server/Main.java (100%)
rename {src => server/src}/main/java/mc/server/di/NetworkComponent.java (100%)
rename {src => server/src}/main/java/mc/server/di/NetworkModule.java (100%)
rename {src => server/src}/main/java/mc/server/network/Server.java (100%)
rename {src => server/src}/main/java/mc/server/network/netty/NettyServer.java (100%)
rename {src => server/src}/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java (100%)
rename {src => server/src}/main/java/mc/server/network/netty/handler/HandshakeHandler.java (100%)
rename {src => server/src}/main/java/mc/server/network/netty/handler/LoginHandler.java (100%)
rename {src => server/src}/main/java/mc/server/network/netty/handler/StatusHandler.java (100%)
rename {src => server/src}/main/resources/logback.xml (100%)
rename {src => server/src}/test/java/mc/protocol/io/NetByteBufReadTest.java (100%)
rename {src => server/src}/test/java/mc/protocol/io/NetByteBufWriteTest.java (100%)
diff --git a/logic.gradle b/logic.gradle
index 0e9a252..9254004 100644
--- a/logic.gradle
+++ b/logic.gradle
@@ -1,3 +1,5 @@
+apply plugin: 'java'
+
String getProperty1(String propertyName1, String propertyName2) {
return (String) (project.hasProperty(propertyName1) ? project.property(propertyName1) : project.property(propertyName2))
}
diff --git a/build.gradle b/server/build.gradle
similarity index 95%
rename from build.gradle
rename to server/build.gradle
index 3180acf..2155b25 100644
--- a/build.gradle
+++ b/server/build.gradle
@@ -3,14 +3,11 @@
gradle run
*/
-plugins {
- id 'java'
- id 'application'
-}
-
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
apply from: rootDir.toPath().resolve('libs.gradle').toFile()
+apply plugin: 'application'
+
dependencies {
annotationProcessor libs.lombok
compileOnly libs.lombok
diff --git a/server/gradle.properties b/server/gradle.properties
new file mode 100644
index 0000000..e2373fb
--- /dev/null
+++ b/server/gradle.properties
@@ -0,0 +1,3 @@
+# suppress inspection "UnusedProperty" for whole file
+module.name=server
+module.version=1.0-SNAPSHOT
\ No newline at end of file
diff --git a/src/main/java/mc/protocol/NetworkAttributes.java b/server/src/main/java/mc/protocol/NetworkAttributes.java
similarity index 100%
rename from src/main/java/mc/protocol/NetworkAttributes.java
rename to server/src/main/java/mc/protocol/NetworkAttributes.java
diff --git a/src/main/java/mc/protocol/State.java b/server/src/main/java/mc/protocol/State.java
similarity index 100%
rename from src/main/java/mc/protocol/State.java
rename to server/src/main/java/mc/protocol/State.java
diff --git a/src/main/java/mc/protocol/io/DecoderException.java b/server/src/main/java/mc/protocol/io/DecoderException.java
similarity index 100%
rename from src/main/java/mc/protocol/io/DecoderException.java
rename to server/src/main/java/mc/protocol/io/DecoderException.java
diff --git a/src/main/java/mc/protocol/io/NetByteBuf.java b/server/src/main/java/mc/protocol/io/NetByteBuf.java
similarity index 100%
rename from src/main/java/mc/protocol/io/NetByteBuf.java
rename to server/src/main/java/mc/protocol/io/NetByteBuf.java
diff --git a/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java b/server/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java
similarity index 100%
rename from src/main/java/mc/protocol/io/codec/ProtocolDecoder.java
rename to server/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java
diff --git a/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java b/server/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java
similarity index 100%
rename from src/main/java/mc/protocol/io/codec/ProtocolEncoder.java
rename to server/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java
diff --git a/src/main/java/mc/protocol/io/codec/ProtocolSplitter.java b/server/src/main/java/mc/protocol/io/codec/ProtocolSplitter.java
similarity index 100%
rename from src/main/java/mc/protocol/io/codec/ProtocolSplitter.java
rename to server/src/main/java/mc/protocol/io/codec/ProtocolSplitter.java
diff --git a/src/main/java/mc/protocol/packets/EmptyPacket.java b/server/src/main/java/mc/protocol/packets/EmptyPacket.java
similarity index 100%
rename from src/main/java/mc/protocol/packets/EmptyPacket.java
rename to server/src/main/java/mc/protocol/packets/EmptyPacket.java
diff --git a/src/main/java/mc/protocol/packets/Packet.java b/server/src/main/java/mc/protocol/packets/Packet.java
similarity index 100%
rename from src/main/java/mc/protocol/packets/Packet.java
rename to server/src/main/java/mc/protocol/packets/Packet.java
diff --git a/src/main/java/mc/protocol/packets/PacketDirection.java b/server/src/main/java/mc/protocol/packets/PacketDirection.java
similarity index 100%
rename from src/main/java/mc/protocol/packets/PacketDirection.java
rename to server/src/main/java/mc/protocol/packets/PacketDirection.java
diff --git a/src/main/java/mc/protocol/packets/UnknownPacket.java b/server/src/main/java/mc/protocol/packets/UnknownPacket.java
similarity index 100%
rename from src/main/java/mc/protocol/packets/UnknownPacket.java
rename to server/src/main/java/mc/protocol/packets/UnknownPacket.java
diff --git a/src/main/java/mc/protocol/packets/client/HandshakePacket.java b/server/src/main/java/mc/protocol/packets/client/HandshakePacket.java
similarity index 100%
rename from src/main/java/mc/protocol/packets/client/HandshakePacket.java
rename to server/src/main/java/mc/protocol/packets/client/HandshakePacket.java
diff --git a/src/main/java/mc/protocol/packets/client/LoginStartPacket.java b/server/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
similarity index 100%
rename from src/main/java/mc/protocol/packets/client/LoginStartPacket.java
rename to server/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
diff --git a/src/main/java/mc/protocol/packets/client/StatusServerRequest.java b/server/src/main/java/mc/protocol/packets/client/StatusServerRequest.java
similarity index 100%
rename from src/main/java/mc/protocol/packets/client/StatusServerRequest.java
rename to server/src/main/java/mc/protocol/packets/client/StatusServerRequest.java
diff --git a/src/main/java/mc/protocol/packets/server/DisconnectPacket.java b/server/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
similarity index 100%
rename from src/main/java/mc/protocol/packets/server/DisconnectPacket.java
rename to server/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
diff --git a/src/main/java/mc/protocol/packets/server/StatusServerResponse.java b/server/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
similarity index 100%
rename from src/main/java/mc/protocol/packets/server/StatusServerResponse.java
rename to server/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
diff --git a/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
similarity index 100%
rename from src/main/java/mc/server/Main.java
rename to server/src/main/java/mc/server/Main.java
diff --git a/src/main/java/mc/server/di/NetworkComponent.java b/server/src/main/java/mc/server/di/NetworkComponent.java
similarity index 100%
rename from src/main/java/mc/server/di/NetworkComponent.java
rename to server/src/main/java/mc/server/di/NetworkComponent.java
diff --git a/src/main/java/mc/server/di/NetworkModule.java b/server/src/main/java/mc/server/di/NetworkModule.java
similarity index 100%
rename from src/main/java/mc/server/di/NetworkModule.java
rename to server/src/main/java/mc/server/di/NetworkModule.java
diff --git a/src/main/java/mc/server/network/Server.java b/server/src/main/java/mc/server/network/Server.java
similarity index 100%
rename from src/main/java/mc/server/network/Server.java
rename to server/src/main/java/mc/server/network/Server.java
diff --git a/src/main/java/mc/server/network/netty/NettyServer.java b/server/src/main/java/mc/server/network/netty/NettyServer.java
similarity index 100%
rename from src/main/java/mc/server/network/netty/NettyServer.java
rename to server/src/main/java/mc/server/network/netty/NettyServer.java
diff --git a/src/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java b/server/src/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java
similarity index 100%
rename from src/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java
rename to server/src/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java
diff --git a/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java b/server/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
similarity index 100%
rename from src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
rename to server/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
diff --git a/src/main/java/mc/server/network/netty/handler/LoginHandler.java b/server/src/main/java/mc/server/network/netty/handler/LoginHandler.java
similarity index 100%
rename from src/main/java/mc/server/network/netty/handler/LoginHandler.java
rename to server/src/main/java/mc/server/network/netty/handler/LoginHandler.java
diff --git a/src/main/java/mc/server/network/netty/handler/StatusHandler.java b/server/src/main/java/mc/server/network/netty/handler/StatusHandler.java
similarity index 100%
rename from src/main/java/mc/server/network/netty/handler/StatusHandler.java
rename to server/src/main/java/mc/server/network/netty/handler/StatusHandler.java
diff --git a/src/main/resources/logback.xml b/server/src/main/resources/logback.xml
similarity index 100%
rename from src/main/resources/logback.xml
rename to server/src/main/resources/logback.xml
diff --git a/src/test/java/mc/protocol/io/NetByteBufReadTest.java b/server/src/test/java/mc/protocol/io/NetByteBufReadTest.java
similarity index 100%
rename from src/test/java/mc/protocol/io/NetByteBufReadTest.java
rename to server/src/test/java/mc/protocol/io/NetByteBufReadTest.java
diff --git a/src/test/java/mc/protocol/io/NetByteBufWriteTest.java b/server/src/test/java/mc/protocol/io/NetByteBufWriteTest.java
similarity index 100%
rename from src/test/java/mc/protocol/io/NetByteBufWriteTest.java
rename to server/src/test/java/mc/protocol/io/NetByteBufWriteTest.java
From fcfcb16e6daeebbf13425b8adfc206807534ec2e Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Mon, 26 Apr 2021 15:27:59 +0300
Subject: [PATCH 09/34] =?UTF-8?q?=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB?=
=?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20mc.protocol=20=D0=B8=20mc.server=20?=
=?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=BC=D0=BE=D0=B4=D1=83=D0=BB?=
=?UTF-8?q?=D0=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.MD | 10 ++++++-
libs.gradle | 7 ++++-
logic.gradle | 27 +++++++++++++++--
protocol/build.gradle | 8 +++++
protocol/gradle.properties | 3 ++
.../java/mc/protocol/NetworkAttributes.java | 0
.../src/main/java/mc/protocol/State.java | 0
.../java/mc/protocol/io/DecoderException.java | 0
.../main/java/mc/protocol/io/NetByteBuf.java | 0
.../mc/protocol/io/codec/ProtocolDecoder.java | 0
.../mc/protocol/io/codec/ProtocolEncoder.java | 0
.../protocol/io/codec/ProtocolSplitter.java | 0
.../java/mc/protocol/packets/EmptyPacket.java | 0
.../main/java/mc/protocol/packets/Packet.java | 0
.../mc/protocol/packets/PacketDirection.java | 0
.../mc/protocol/packets/UnknownPacket.java | 0
.../packets/client/HandshakePacket.java | 0
.../packets/client/LoginStartPacket.java | 0
.../packets/client/StatusServerRequest.java | 0
.../packets/server/DisconnectPacket.java | 0
.../packets/server/StatusServerResponse.java | 0
.../mc/protocol/io/NetByteBufReadTest.java | 1 -
.../mc/protocol/io/NetByteBufWriteTest.java | 0
server/build.gradle | 30 ++++---------------
settings.gradle | 1 +
25 files changed, 58 insertions(+), 29 deletions(-)
create mode 100644 protocol/build.gradle
create mode 100644 protocol/gradle.properties
rename {server => protocol}/src/main/java/mc/protocol/NetworkAttributes.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/State.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/io/DecoderException.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/io/NetByteBuf.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/io/codec/ProtocolSplitter.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/packets/EmptyPacket.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/packets/Packet.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/packets/PacketDirection.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/packets/UnknownPacket.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/packets/client/HandshakePacket.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/packets/client/LoginStartPacket.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/packets/client/StatusServerRequest.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/packets/server/DisconnectPacket.java (100%)
rename {server => protocol}/src/main/java/mc/protocol/packets/server/StatusServerResponse.java (100%)
rename {server => protocol}/src/test/java/mc/protocol/io/NetByteBufReadTest.java (99%)
rename {server => protocol}/src/test/java/mc/protocol/io/NetByteBufWriteTest.java (100%)
diff --git a/README.MD b/README.MD
index 3d7113f..f0e5040 100644
--- a/README.MD
+++ b/README.MD
@@ -6,4 +6,12 @@
---
-* Java 11
\ No newline at end of file
+* Java 11
+
+---
+
+## Запуск
+
+```shell
+gradle :server:run
+```
\ No newline at end of file
diff --git a/libs.gradle b/libs.gradle
index 600bd97..365ee1a 100644
--- a/libs.gradle
+++ b/libs.gradle
@@ -1,5 +1,6 @@
//file:noinspection GroovyAssignabilityCheck
//file:noinspection GrUnresolvedAccess
+//file:noinspection GroovyConstructorNamedArguments
def slf4j_version = '1.7.30'
def logback_version = '1.2.3'
@@ -26,7 +27,11 @@ ext {
annotationProcessor: "com.google.dagger:dagger-compiler:${dagger2_version}"
]
- libs.junit5 = [
+ libs.test = [
+ logger: "org.slf4j:slf4j-simple:${slf4j_version}"
+ ]
+
+ libs.test.junit5 = [
api : "org.junit.jupiter:junit-jupiter-api:${junit_version}",
//runtime only
engine: "org.junit.jupiter:junit-jupiter-engine:${junit_version}",
diff --git a/logic.gradle b/logic.gradle
index 9254004..eb5630f 100644
--- a/logic.gradle
+++ b/logic.gradle
@@ -1,4 +1,6 @@
+//file:noinspection GrUnresolvedAccess
apply plugin: 'java'
+apply from: rootDir.toPath().resolve('libs.gradle').toFile()
String getProperty1(String propertyName1, String propertyName2) {
return (String) (project.hasProperty(propertyName1) ? project.property(propertyName1) : project.property(propertyName2))
@@ -6,7 +8,7 @@ String getProperty1(String propertyName1, String propertyName2) {
project.group = getProperty1('module.group', 'project.group')
project.version = getProperty1('module.version', 'project.version')
-project.jar.archiveBaseName.set(getProperty1('module.name', 'project.name'))
+jar.archiveBaseName.set(getProperty1('module.name', 'project.name'))
compileJava {
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_11
@@ -16,4 +18,25 @@ compileJava {
repositories {
mavenLocal()
mavenCentral()
-}
\ No newline at end of file
+}
+
+dependencies {
+ annotationProcessor libs.lombok
+ compileOnly libs.lombok
+ compileOnly libs.annotations
+
+ implementation libs.logger.slf4j
+
+ implementation libs.dagger2.implementation
+ annotationProcessor libs.dagger2.annotationProcessor
+
+ testImplementation libs.test.junit5.api
+ testImplementation libs.test.junit5.params
+ testRuntimeOnly libs.test.junit5.engine
+
+ testRuntimeOnly libs.test.logger
+}
+
+test {
+ useJUnitPlatform()
+}
diff --git a/protocol/build.gradle b/protocol/build.gradle
new file mode 100644
index 0000000..4e4b0da
--- /dev/null
+++ b/protocol/build.gradle
@@ -0,0 +1,8 @@
+apply from: rootDir.toPath().resolve('logic.gradle').toFile()
+
+dependencies {
+ implementation 'io.netty:netty-all:4.1.22.Final'
+ implementation libs.guava
+
+ testImplementation libs.lang3
+}
diff --git a/protocol/gradle.properties b/protocol/gradle.properties
new file mode 100644
index 0000000..572e805
--- /dev/null
+++ b/protocol/gradle.properties
@@ -0,0 +1,3 @@
+# suppress inspection "UnusedProperty" for whole file
+module.name=protocol
+module.version=1.0-SNAPSHOT
\ No newline at end of file
diff --git a/server/src/main/java/mc/protocol/NetworkAttributes.java b/protocol/src/main/java/mc/protocol/NetworkAttributes.java
similarity index 100%
rename from server/src/main/java/mc/protocol/NetworkAttributes.java
rename to protocol/src/main/java/mc/protocol/NetworkAttributes.java
diff --git a/server/src/main/java/mc/protocol/State.java b/protocol/src/main/java/mc/protocol/State.java
similarity index 100%
rename from server/src/main/java/mc/protocol/State.java
rename to protocol/src/main/java/mc/protocol/State.java
diff --git a/server/src/main/java/mc/protocol/io/DecoderException.java b/protocol/src/main/java/mc/protocol/io/DecoderException.java
similarity index 100%
rename from server/src/main/java/mc/protocol/io/DecoderException.java
rename to protocol/src/main/java/mc/protocol/io/DecoderException.java
diff --git a/server/src/main/java/mc/protocol/io/NetByteBuf.java b/protocol/src/main/java/mc/protocol/io/NetByteBuf.java
similarity index 100%
rename from server/src/main/java/mc/protocol/io/NetByteBuf.java
rename to protocol/src/main/java/mc/protocol/io/NetByteBuf.java
diff --git a/server/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java b/protocol/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java
similarity index 100%
rename from server/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java
rename to protocol/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java
diff --git a/server/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java b/protocol/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java
similarity index 100%
rename from server/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java
rename to protocol/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java
diff --git a/server/src/main/java/mc/protocol/io/codec/ProtocolSplitter.java b/protocol/src/main/java/mc/protocol/io/codec/ProtocolSplitter.java
similarity index 100%
rename from server/src/main/java/mc/protocol/io/codec/ProtocolSplitter.java
rename to protocol/src/main/java/mc/protocol/io/codec/ProtocolSplitter.java
diff --git a/server/src/main/java/mc/protocol/packets/EmptyPacket.java b/protocol/src/main/java/mc/protocol/packets/EmptyPacket.java
similarity index 100%
rename from server/src/main/java/mc/protocol/packets/EmptyPacket.java
rename to protocol/src/main/java/mc/protocol/packets/EmptyPacket.java
diff --git a/server/src/main/java/mc/protocol/packets/Packet.java b/protocol/src/main/java/mc/protocol/packets/Packet.java
similarity index 100%
rename from server/src/main/java/mc/protocol/packets/Packet.java
rename to protocol/src/main/java/mc/protocol/packets/Packet.java
diff --git a/server/src/main/java/mc/protocol/packets/PacketDirection.java b/protocol/src/main/java/mc/protocol/packets/PacketDirection.java
similarity index 100%
rename from server/src/main/java/mc/protocol/packets/PacketDirection.java
rename to protocol/src/main/java/mc/protocol/packets/PacketDirection.java
diff --git a/server/src/main/java/mc/protocol/packets/UnknownPacket.java b/protocol/src/main/java/mc/protocol/packets/UnknownPacket.java
similarity index 100%
rename from server/src/main/java/mc/protocol/packets/UnknownPacket.java
rename to protocol/src/main/java/mc/protocol/packets/UnknownPacket.java
diff --git a/server/src/main/java/mc/protocol/packets/client/HandshakePacket.java b/protocol/src/main/java/mc/protocol/packets/client/HandshakePacket.java
similarity index 100%
rename from server/src/main/java/mc/protocol/packets/client/HandshakePacket.java
rename to protocol/src/main/java/mc/protocol/packets/client/HandshakePacket.java
diff --git a/server/src/main/java/mc/protocol/packets/client/LoginStartPacket.java b/protocol/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
similarity index 100%
rename from server/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
rename to protocol/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
diff --git a/server/src/main/java/mc/protocol/packets/client/StatusServerRequest.java b/protocol/src/main/java/mc/protocol/packets/client/StatusServerRequest.java
similarity index 100%
rename from server/src/main/java/mc/protocol/packets/client/StatusServerRequest.java
rename to protocol/src/main/java/mc/protocol/packets/client/StatusServerRequest.java
diff --git a/server/src/main/java/mc/protocol/packets/server/DisconnectPacket.java b/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
similarity index 100%
rename from server/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
rename to protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
diff --git a/server/src/main/java/mc/protocol/packets/server/StatusServerResponse.java b/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
similarity index 100%
rename from server/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
rename to protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
diff --git a/server/src/test/java/mc/protocol/io/NetByteBufReadTest.java b/protocol/src/test/java/mc/protocol/io/NetByteBufReadTest.java
similarity index 99%
rename from server/src/test/java/mc/protocol/io/NetByteBufReadTest.java
rename to protocol/src/test/java/mc/protocol/io/NetByteBufReadTest.java
index c48b6b4..6337ec5 100644
--- a/server/src/test/java/mc/protocol/io/NetByteBufReadTest.java
+++ b/protocol/src/test/java/mc/protocol/io/NetByteBufReadTest.java
@@ -1,6 +1,5 @@
package mc.protocol.io;
-import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
diff --git a/server/src/test/java/mc/protocol/io/NetByteBufWriteTest.java b/protocol/src/test/java/mc/protocol/io/NetByteBufWriteTest.java
similarity index 100%
rename from server/src/test/java/mc/protocol/io/NetByteBufWriteTest.java
rename to protocol/src/test/java/mc/protocol/io/NetByteBufWriteTest.java
diff --git a/server/build.gradle b/server/build.gradle
index 2155b25..68acb11 100644
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -1,41 +1,23 @@
/*
Запуск
- gradle run
+ gradle :server:run
*/
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
-apply from: rootDir.toPath().resolve('libs.gradle').toFile()
-
apply plugin: 'application'
+application {
+ mainClassName = 'mc.server.Main'
+}
+
dependencies {
- annotationProcessor libs.lombok
- compileOnly libs.lombok
- compileOnly libs.annotations
+ implementation project(':protocol')
- implementation libs.logger.slf4j
implementation libs.logger.logback
- implementation libs.dagger2.implementation
- annotationProcessor libs.dagger2.annotationProcessor
-
implementation platform('io.projectreactor:reactor-bom:2020.0.6')
implementation 'io.projectreactor:reactor-core'
implementation 'io.netty:netty-all:4.1.22.Final'
implementation libs.guava
-
- testImplementation libs.junit5.api
- testImplementation libs.junit5.params
- testRuntimeOnly libs.junit5.engine
-
- testImplementation libs.lang3
-}
-
-application {
- mainClassName = 'mc.server.Main'
-}
-
-test {
- useJUnitPlatform()
}
diff --git a/settings.gradle b/settings.gradle
index 925cad0..03dd498 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -10,4 +10,5 @@ rootProject.projectDir.toPath().resolve('gradle.properties').readLines().forEach
rootProject.name = map.get('project.name')
+include('protocol')
include('server')
\ No newline at end of file
From eff6dcf1484368f4435ffc1cebd0f35d6fde2f05 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Mon, 26 Apr 2021 18:29:50 +0300
Subject: [PATCH 10/34] =?UTF-8?q?(BROKEN)=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?=
=?UTF-8?q?=D0=BB=D0=B5=D0=BD=20PingPacket?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
protocol/src/main/java/mc/protocol/State.java | 11 ++++-
.../java/mc/protocol/packets/PingPacket.java | 41 +++++++++++++++++++
.../packets/client/LoginStartPacket.java | 2 -
.../main/java/mc/server/di/NetworkModule.java | 12 +++++-
.../netty/handler/HandshakeHandler.java | 2 +
.../netty/handler/KeepAliveHandler.java | 16 ++++++++
.../network/netty/handler/StatusHandler.java | 2 +-
7 files changed, 79 insertions(+), 7 deletions(-)
create mode 100644 protocol/src/main/java/mc/protocol/packets/PingPacket.java
create mode 100644 server/src/main/java/mc/server/network/netty/handler/KeepAliveHandler.java
diff --git a/protocol/src/main/java/mc/protocol/State.java b/protocol/src/main/java/mc/protocol/State.java
index 3d38333..b9b9d53 100644
--- a/protocol/src/main/java/mc/protocol/State.java
+++ b/protocol/src/main/java/mc/protocol/State.java
@@ -6,6 +6,7 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
import mc.protocol.packets.Packet;
import mc.protocol.packets.PacketDirection;
+import mc.protocol.packets.PingPacket;
import mc.protocol.packets.client.HandshakePacket;
import mc.protocol.packets.client.LoginStartPacket;
import mc.protocol.packets.client.StatusServerRequest;
@@ -23,9 +24,15 @@ public enum State {
),
STATUS(1,
// server bound
- ImmutableBiMap.of(0x00, StatusServerRequest.class),
+ ImmutableBiMap.of(
+ 0x00, StatusServerRequest.class,
+ 0x01, PingPacket.class
+ ),
// client bound
- ImmutableBiMap.of(0x00, StatusServerResponse.class)
+ ImmutableBiMap.of(
+ 0x00, StatusServerResponse.class,
+ 0x01, PingPacket.class
+ )
),
LOGIN(2,
// server bound
diff --git a/protocol/src/main/java/mc/protocol/packets/PingPacket.java b/protocol/src/main/java/mc/protocol/packets/PingPacket.java
new file mode 100644
index 0000000..81e0b88
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/packets/PingPacket.java
@@ -0,0 +1,41 @@
+package mc.protocol.packets;
+
+import lombok.Data;
+import mc.protocol.io.NetByteBuf;
+
+/**
+ * Пинг-пакет.
+ *
+ * Эхо-пакет, которым проверяется качество соединения между Клиентом и Сервером .
+ *
+ * По спецификации:
+ *
+ * если Сервер не ответил Клиенту в течении 20 секунд, Клиент отключается
+ * и выдаёт ошибку "Timed out" .
+ * если Клиент не отвечает Серверу в течении 30 секунд, Сервер отключает Клиента .
+ *
+ *
+ * Структура пакета
+ *
+ * | FIELD | TYPE | NOTES |
+ * |---------|------|------------------------|
+ * | Payload | Long | Любое уникальное число |
+ *
+ *
+ * @see Keep Alive
+ */
+@Data
+public class PingPacket implements Packet {
+
+ private Long payload;
+
+ @Override
+ public void readSelf(NetByteBuf netByteBuf) {
+ payload = netByteBuf.readLong();
+ }
+
+ @Override
+ public void writeSelf(NetByteBuf netByteBuf) {
+ netByteBuf.writeLong(payload);
+ }
+}
diff --git a/protocol/src/main/java/mc/protocol/packets/client/LoginStartPacket.java b/protocol/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
index 6fa953e..75ebe04 100644
--- a/protocol/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
+++ b/protocol/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
@@ -4,7 +4,6 @@ import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
-import mc.protocol.State;
import mc.protocol.io.NetByteBuf;
import mc.protocol.packets.Packet;
@@ -21,7 +20,6 @@ import mc.protocol.packets.Packet;
*
*
* @see Login start
- * @see State
*/
@NoArgsConstructor
@Getter
diff --git a/server/src/main/java/mc/server/di/NetworkModule.java b/server/src/main/java/mc/server/di/NetworkModule.java
index c5ca566..851566e 100644
--- a/server/src/main/java/mc/server/di/NetworkModule.java
+++ b/server/src/main/java/mc/server/di/NetworkModule.java
@@ -18,6 +18,7 @@ import mc.protocol.io.codec.ProtocolSplitter;
import mc.server.network.Server;
import mc.server.network.netty.handler.HandshakeHandler;
import mc.server.network.netty.NettyServer;
+import mc.server.network.netty.handler.KeepAliveHandler;
import mc.server.network.netty.handler.LoginHandler;
import mc.server.network.netty.handler.StatusHandler;
@@ -59,7 +60,8 @@ public class NetworkModule {
@Provides
Map provideChannelHandlerMap(
Provider statusHandlerProvider,
- Provider loginHandlerProvider
+ Provider loginHandlerProvider,
+ Provider keepAliveHandlerProvider
) {
Map map = new LinkedHashMap<>();
@@ -67,7 +69,8 @@ public class NetworkModule {
map.put("protocol_splitter", new ProtocolSplitter());
map.put("protocol_decoder", new ProtocolDecoder(true));
map.put("protocol_encoder", new ProtocolEncoder());
- map.put("handshake_handler", new HandshakeHandler(statusHandlerProvider, loginHandlerProvider));
+ map.put("handshake_handler", new HandshakeHandler(
+ statusHandlerProvider, loginHandlerProvider, keepAliveHandlerProvider));
return map;
}
@@ -81,4 +84,9 @@ public class NetworkModule {
LoginHandler provideLoginHandler() {
return new LoginHandler();
}
+
+ @Provides
+ KeepAliveHandler provideKeepAliveHandler() {
+ return new KeepAliveHandler();
+ }
}
diff --git a/server/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java b/server/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
index 5f31d3e..02b19e0 100644
--- a/server/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
+++ b/server/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
@@ -15,6 +15,7 @@ public class HandshakeHandler extends AbstractPacketHandler {
private final Provider statusHandlerProvider;
private final Provider loginHandlerProvider;
+ private final Provider keepAliveHandlerProvider;
@Override
protected void channelRead1(ChannelHandlerContext ctx, HandshakePacket packet) {
@@ -24,6 +25,7 @@ public class HandshakeHandler extends AbstractPacketHandler {
if (State.STATUS == packet.getNextState()) {
ctx.pipeline().replace("handshake_handler", "status_handler", statusHandlerProvider.get());
+ ctx.pipeline().addAfter("status_handler", "keepalive_handler", keepAliveHandlerProvider.get());
} else if (State.LOGIN == packet.getNextState()) {
ctx.channel().pipeline().replace("handshake_handler", "login_handler", loginHandlerProvider.get());
}
diff --git a/server/src/main/java/mc/server/network/netty/handler/KeepAliveHandler.java b/server/src/main/java/mc/server/network/netty/handler/KeepAliveHandler.java
new file mode 100644
index 0000000..ea69c2c
--- /dev/null
+++ b/server/src/main/java/mc/server/network/netty/handler/KeepAliveHandler.java
@@ -0,0 +1,16 @@
+package mc.server.network.netty.handler;
+
+import io.netty.channel.ChannelHandlerContext;
+import lombok.extern.slf4j.Slf4j;
+import mc.protocol.packets.PingPacket;
+
+@Slf4j
+public class KeepAliveHandler extends AbstractPacketHandler {
+
+ @Override
+ protected void channelRead1(ChannelHandlerContext ctx, PingPacket packet) {
+ log.info("{}", packet);
+
+ ctx.writeAndFlush(packet).channel().disconnect();
+ }
+}
diff --git a/server/src/main/java/mc/server/network/netty/handler/StatusHandler.java b/server/src/main/java/mc/server/network/netty/handler/StatusHandler.java
index 0628875..2fbcfe5 100644
--- a/server/src/main/java/mc/server/network/netty/handler/StatusHandler.java
+++ b/server/src/main/java/mc/server/network/netty/handler/StatusHandler.java
@@ -28,6 +28,6 @@ public class StatusHandler extends AbstractPacketHandler {
" }\n" +
"}");
- ctx.channel().writeAndFlush(response).channel().disconnect();
+ ctx.channel().writeAndFlush(response);
}
}
From 2a1992b6dd8a276571360bba1ad6b17a52623dcc Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Tue, 27 Apr 2021 00:10:55 +0300
Subject: [PATCH 11/34] =?UTF-8?q?=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD?=
=?UTF-8?q?=D0=B0=20=D0=B0=D0=B1=D1=81=D1=82=D1=80=D0=B0=D0=BA=D1=86=D0=B8?=
=?UTF-8?q?=D1=8F=20=D0=BD=D0=B0=D0=B4=20NettyServer?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
libs.gradle | 2 +
protocol/build.gradle | 3 +-
.../main/java/mc/protocol/ChannelContext.java | 20 ++++++
.../main/java/mc/protocol/NettyServer.java | 43 +++++++++++++
.../mc/protocol/PacketInboundHandler.java | 21 ++++++
protocol/src/main/java/mc/protocol/State.java | 1 +
.../mc/protocol/di/ProtocolComponent.java | 11 ++++
.../java/mc/protocol/di/ProtocolModule.java | 64 +++++++++----------
.../main/java/mc/protocol/di/ServerScope.java | 10 +++
server/build.gradle | 6 +-
server/src/main/java/mc/server/Main.java | 55 ++++++++++++++--
.../java/mc/server/di/NetworkComponent.java | 10 ---
.../main/java/mc/server/network/Server.java | 6 --
.../mc/server/network/netty/NettyServer.java | 26 --------
.../netty/handler/AbstractPacketHandler.java | 17 -----
.../netty/handler/HandshakeHandler.java | 33 ----------
.../netty/handler/KeepAliveHandler.java | 16 -----
.../network/netty/handler/LoginHandler.java | 18 ------
.../network/netty/handler/StatusHandler.java | 33 ----------
19 files changed, 194 insertions(+), 201 deletions(-)
create mode 100644 protocol/src/main/java/mc/protocol/ChannelContext.java
create mode 100644 protocol/src/main/java/mc/protocol/NettyServer.java
create mode 100644 protocol/src/main/java/mc/protocol/PacketInboundHandler.java
create mode 100644 protocol/src/main/java/mc/protocol/di/ProtocolComponent.java
rename server/src/main/java/mc/server/di/NetworkModule.java => protocol/src/main/java/mc/protocol/di/ProtocolModule.java (52%)
create mode 100644 protocol/src/main/java/mc/protocol/di/ServerScope.java
delete mode 100644 server/src/main/java/mc/server/di/NetworkComponent.java
delete mode 100644 server/src/main/java/mc/server/network/Server.java
delete mode 100644 server/src/main/java/mc/server/network/netty/NettyServer.java
delete mode 100644 server/src/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java
delete mode 100644 server/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
delete mode 100644 server/src/main/java/mc/server/network/netty/handler/KeepAliveHandler.java
delete mode 100644 server/src/main/java/mc/server/network/netty/handler/LoginHandler.java
delete mode 100644 server/src/main/java/mc/server/network/netty/handler/StatusHandler.java
diff --git a/libs.gradle b/libs.gradle
index 365ee1a..d6958eb 100644
--- a/libs.gradle
+++ b/libs.gradle
@@ -13,6 +13,8 @@ ext {
annotations: 'com.google.code.findbugs:jsr305:3.0.2',
guava : 'com.google.guava:guava:30.1-jre',
lang3 : 'org.apache.commons:commons-lang3:3.11',
+ netty : 'io.netty:netty-all:4.1.22.Final',
+ reactor : 'io.projectreactor:reactor-core:3.4.5'
]
libs.logger = [
diff --git a/protocol/build.gradle b/protocol/build.gradle
index 4e4b0da..4677d8a 100644
--- a/protocol/build.gradle
+++ b/protocol/build.gradle
@@ -1,7 +1,8 @@
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
dependencies {
- implementation 'io.netty:netty-all:4.1.22.Final'
+ implementation libs.netty
+ implementation libs.reactor
implementation libs.guava
testImplementation libs.lang3
diff --git a/protocol/src/main/java/mc/protocol/ChannelContext.java b/protocol/src/main/java/mc/protocol/ChannelContext.java
new file mode 100644
index 0000000..ba85b49
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/ChannelContext.java
@@ -0,0 +1,20 @@
+package mc.protocol;
+
+import io.netty.channel.ChannelHandlerContext;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import mc.protocol.packets.Packet;
+
+@RequiredArgsConstructor
+public class ChannelContext {
+
+ @Getter
+ private final ChannelHandlerContext ctx;
+
+ @Getter
+ private final P packet;
+
+ public void setState(State state) {
+ ctx.channel().attr(NetworkAttributes.STATE).set(state);
+ }
+}
diff --git a/protocol/src/main/java/mc/protocol/NettyServer.java b/protocol/src/main/java/mc/protocol/NettyServer.java
new file mode 100644
index 0000000..b2f20fc
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/NettyServer.java
@@ -0,0 +1,43 @@
+package mc.protocol;
+
+import io.netty.bootstrap.ServerBootstrap;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import mc.protocol.di.DaggerProtocolComponent;
+import mc.protocol.di.ProtocolComponent;
+import mc.protocol.packets.Packet;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Sinks;
+
+import java.util.Map;
+
+@SuppressWarnings("rawtypes")
+@Slf4j
+@RequiredArgsConstructor
+public class NettyServer {
+
+ private final ServerBootstrap serverBootstrap;
+ private final Map, Sinks.Many> observedMap;
+
+ public void bind(String host, int port) {
+ log.info("Network starting: {}:{}", host, port);
+
+ try {
+ serverBootstrap.bind(host, port).sync().channel().closeFuture().sync();
+ } catch (InterruptedException e) {
+ if (log.isTraceEnabled()) {
+ log.trace("{}: {}", e.getClass().getSimpleName(), e.getMessage(), e);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Flux> packetFlux(Class packetClass) {
+ return observedMap.get(packetClass).asFlux().map(ChannelContext.class::cast);
+ }
+
+ public static NettyServer createServer() {
+ ProtocolComponent component = DaggerProtocolComponent.create();
+ return component.getNettyServer();
+ }
+}
diff --git a/protocol/src/main/java/mc/protocol/PacketInboundHandler.java b/protocol/src/main/java/mc/protocol/PacketInboundHandler.java
new file mode 100644
index 0000000..451f3b7
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/PacketInboundHandler.java
@@ -0,0 +1,21 @@
+package mc.protocol;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import lombok.RequiredArgsConstructor;
+import mc.protocol.packets.Packet;
+import reactor.core.publisher.Sinks;
+
+import java.util.Map;
+
+@SuppressWarnings("rawtypes")
+@RequiredArgsConstructor
+public class PacketInboundHandler extends SimpleChannelInboundHandler {
+
+ private final Map, Sinks.Many> observedMap;
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, Packet packet) {
+ observedMap.get(packet.getClass()).tryEmitNext(new ChannelContext<>(ctx, packet));
+ }
+}
diff --git a/protocol/src/main/java/mc/protocol/State.java b/protocol/src/main/java/mc/protocol/State.java
index b9b9d53..01c2971 100644
--- a/protocol/src/main/java/mc/protocol/State.java
+++ b/protocol/src/main/java/mc/protocol/State.java
@@ -55,6 +55,7 @@ public enum State {
@Getter
private final int id;
+ @Getter
private final BiMap> serverBoundPackets;
private final BiMap> clientBoundPackets;
diff --git a/protocol/src/main/java/mc/protocol/di/ProtocolComponent.java b/protocol/src/main/java/mc/protocol/di/ProtocolComponent.java
new file mode 100644
index 0000000..a433211
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/di/ProtocolComponent.java
@@ -0,0 +1,11 @@
+package mc.protocol.di;
+
+import dagger.Component;
+import mc.protocol.NettyServer;
+
+@Component(modules = ProtocolModule.class)
+@ServerScope
+public interface ProtocolComponent {
+
+ NettyServer getNettyServer();
+}
diff --git a/server/src/main/java/mc/server/di/NetworkModule.java b/protocol/src/main/java/mc/protocol/di/ProtocolModule.java
similarity index 52%
rename from server/src/main/java/mc/server/di/NetworkModule.java
rename to protocol/src/main/java/mc/protocol/di/ProtocolModule.java
index 851566e..3ee3ba3 100644
--- a/server/src/main/java/mc/server/di/NetworkModule.java
+++ b/protocol/src/main/java/mc/protocol/di/ProtocolModule.java
@@ -1,5 +1,6 @@
-package mc.server.di;
+package mc.protocol.di;
+import com.google.common.collect.ImmutableMap;
import dagger.Module;
import dagger.Provides;
import io.netty.bootstrap.ServerBootstrap;
@@ -11,28 +12,29 @@ 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.extern.slf4j.Slf4j;
+import mc.protocol.ChannelContext;
+import mc.protocol.NettyServer;
+import mc.protocol.PacketInboundHandler;
+import mc.protocol.State;
import mc.protocol.io.codec.ProtocolDecoder;
import mc.protocol.io.codec.ProtocolEncoder;
import mc.protocol.io.codec.ProtocolSplitter;
-import mc.server.network.Server;
-import mc.server.network.netty.handler.HandshakeHandler;
-import mc.server.network.netty.NettyServer;
-import mc.server.network.netty.handler.KeepAliveHandler;
-import mc.server.network.netty.handler.LoginHandler;
-import mc.server.network.netty.handler.StatusHandler;
+import mc.protocol.packets.Packet;
+import reactor.core.publisher.Sinks;
import javax.inject.Provider;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.stream.Stream;
@Module
-@Slf4j
-public class NetworkModule {
+public class ProtocolModule {
+ @SuppressWarnings("rawtypes")
@Provides
- Server provideServer(ServerBootstrap serverBootstrap) {
- return new NettyServer(serverBootstrap);
+ NettyServer provideServer(ServerBootstrap serverBootstrap,
+ Map, Sinks.Many> observedMap) {
+ return new NettyServer(serverBootstrap, observedMap);
}
@Provides
@@ -47,7 +49,9 @@ public class NetworkModule {
}
@Provides
- ChannelInitializer provideChannelChannelInitializer(Provider> channelHandlerMapProvider) {
+ ChannelInitializer provideChannelChannelInitializer(
+ Provider> channelHandlerMapProvider) {
+
return new ChannelInitializer<>() {
@Override
protected void initChannel(SocketChannel socketChannel) {
@@ -57,36 +61,32 @@ public class NetworkModule {
};
}
+ @SuppressWarnings("rawtypes")
@Provides
Map provideChannelHandlerMap(
- Provider statusHandlerProvider,
- Provider loginHandlerProvider,
- Provider keepAliveHandlerProvider
- ) {
+ Map, Sinks.Many> observedMap) {
+
Map map = new LinkedHashMap<>();
+ map.put("packet_splitter", new ProtocolSplitter());
map.put("logger", new LoggingHandler(LogLevel.DEBUG));
- map.put("protocol_splitter", new ProtocolSplitter());
- map.put("protocol_decoder", new ProtocolDecoder(true));
- map.put("protocol_encoder", new ProtocolEncoder());
- map.put("handshake_handler", new HandshakeHandler(
- statusHandlerProvider, loginHandlerProvider, keepAliveHandlerProvider));
+ map.put("packet_decoder", new ProtocolDecoder(true));
+ map.put("packet_encoder", new ProtocolEncoder());
+ map.put("packet_handler", new PacketInboundHandler(observedMap));
return map;
}
+ @SuppressWarnings("rawtypes")
@Provides
- StatusHandler provideStatusHandler() {
- return new StatusHandler();
- }
+ @ServerScope
+ Map, Sinks.Many> provideObservedMap() {
+ ImmutableMap.Builder, Sinks.Many> builder = ImmutableMap.builder();
- @Provides
- LoginHandler provideLoginHandler() {
- return new LoginHandler();
- }
+ Stream.of(State.values())
+ .flatMap(state -> state.getServerBoundPackets().values().stream())
+ .forEach(packetClass -> builder.put(packetClass, Sinks.many().multicast().directBestEffort()));
- @Provides
- KeepAliveHandler provideKeepAliveHandler() {
- return new KeepAliveHandler();
+ return builder.build();
}
}
diff --git a/protocol/src/main/java/mc/protocol/di/ServerScope.java b/protocol/src/main/java/mc/protocol/di/ServerScope.java
new file mode 100644
index 0000000..b90e94e
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/di/ServerScope.java
@@ -0,0 +1,10 @@
+package mc.protocol.di;
+
+import javax.inject.Scope;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Scope
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ServerScope {
+}
diff --git a/server/build.gradle b/server/build.gradle
index 68acb11..491cc7b 100644
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -15,9 +15,7 @@ dependencies {
implementation libs.logger.logback
- implementation platform('io.projectreactor:reactor-bom:2020.0.6')
- implementation 'io.projectreactor:reactor-core'
-
- implementation 'io.netty:netty-all:4.1.22.Final'
+ implementation libs.netty
+ implementation libs.reactor
implementation libs.guava
}
diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
index a435547..d0a445b 100644
--- a/server/src/main/java/mc/server/Main.java
+++ b/server/src/main/java/mc/server/Main.java
@@ -1,9 +1,13 @@
package mc.server;
import lombok.extern.slf4j.Slf4j;
-import mc.server.di.DaggerNetworkComponent;
-import mc.server.di.NetworkComponent;
-import mc.server.network.Server;
+import mc.protocol.NettyServer;
+import mc.protocol.packets.PingPacket;
+import mc.protocol.packets.client.HandshakePacket;
+import mc.protocol.packets.client.LoginStartPacket;
+import mc.protocol.packets.client.StatusServerRequest;
+import mc.protocol.packets.server.DisconnectPacket;
+import mc.protocol.packets.server.StatusServerResponse;
@Slf4j
public class Main {
@@ -11,8 +15,49 @@ public class Main {
public static void main(String[] args) {
log.info("hello");
- NetworkComponent networkComponent = DaggerNetworkComponent.create();
- Server server = networkComponent.getServer();
+ NettyServer server = NettyServer.createServer();
+
+ server.packetFlux(HandshakePacket.class)
+ .doOnNext(channel -> log.info("{}", channel.getPacket()))
+ .subscribe(channel -> channel.setState(channel.getPacket().getNextState()));
+
+ server.packetFlux(PingPacket.class)
+ .doOnNext(channel -> log.info("{}", channel.getPacket()))
+ .subscribe(channel -> channel.getCtx().writeAndFlush(channel.getPacket()).channel().disconnect());
+
+ server.packetFlux(StatusServerRequest.class)
+ .doOnNext(channel -> log.info("{}", channel.getPacket()))
+ .subscribe(channel -> {
+ StatusServerResponse response = new StatusServerResponse();
+ response.setInfo("{\n" +
+ " \"version\": {\n" +
+ " \"name\": \"1.12.2\",\n" +
+ " \"protocol\": 340\n" +
+ " },\n" +
+ " \"players\": {\n" +
+ " \"max\": 0,\n" +
+ " \"online\": 0,\n" +
+ " \"sample\": []\n" +
+ " },\n" +
+ " \"description\": {\n" +
+ " \"text\": \"Hello world\"\n" +
+ " }\n" +
+ "}");
+
+ channel.getCtx().writeAndFlush(response);
+ });
+
+ server.packetFlux(LoginStartPacket.class)
+ .doOnNext(channel -> log.info("{}", channel.getPacket()))
+ .subscribe(channel -> {
+ DisconnectPacket disconnectPacket = new DisconnectPacket();
+ disconnectPacket.setReason("{\n" +
+ " \"text\": \"Server is not available.\"\n" +
+ "}");
+
+ channel.getCtx().writeAndFlush(disconnectPacket).channel().disconnect();
+ });
+
server.bind("127.0.0.1", 25565);
}
}
diff --git a/server/src/main/java/mc/server/di/NetworkComponent.java b/server/src/main/java/mc/server/di/NetworkComponent.java
deleted file mode 100644
index ae73ed9..0000000
--- a/server/src/main/java/mc/server/di/NetworkComponent.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package mc.server.di;
-
-import dagger.Component;
-import mc.server.network.Server;
-
-@Component(modules = NetworkModule.class)
-public interface NetworkComponent {
-
- Server getServer();
-}
diff --git a/server/src/main/java/mc/server/network/Server.java b/server/src/main/java/mc/server/network/Server.java
deleted file mode 100644
index b346a17..0000000
--- a/server/src/main/java/mc/server/network/Server.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package mc.server.network;
-
-public interface Server {
-
- void bind(String host, int port);
-}
diff --git a/server/src/main/java/mc/server/network/netty/NettyServer.java b/server/src/main/java/mc/server/network/netty/NettyServer.java
deleted file mode 100644
index 881914c..0000000
--- a/server/src/main/java/mc/server/network/netty/NettyServer.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package mc.server.network.netty;
-
-import io.netty.bootstrap.ServerBootstrap;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import mc.server.network.Server;
-
-@Slf4j
-@RequiredArgsConstructor
-public class NettyServer implements Server {
-
- private final ServerBootstrap serverBootstrap;
-
- @Override
- public void bind(String host, int port) {
- log.info("Network starting: {}:{}", host, port);
-
- try {
- serverBootstrap.bind(host, port).sync().channel().closeFuture().sync();
- } catch (InterruptedException e) {
- if (log.isTraceEnabled()) {
- log.trace("{}: {}", e.getClass().getSimpleName(), e.getMessage(), e);
- }
- }
- }
-}
diff --git a/server/src/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java b/server/src/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java
deleted file mode 100644
index 3d2d900..0000000
--- a/server/src/main/java/mc/server/network/netty/handler/AbstractPacketHandler.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package mc.server.network.netty.handler;
-
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-import mc.protocol.packets.Packet;
-
-public abstract class AbstractPacketHandler extends SimpleChannelInboundHandler {
-
- @SuppressWarnings("unchecked")
- @Override
- protected void channelRead0(ChannelHandlerContext ctx, Packet msg) throws Exception {
- channelRead1(ctx, (P) msg);
- }
-
- @SuppressWarnings("java:S112")
- protected abstract void channelRead1(ChannelHandlerContext ctx, P packet) throws Exception;
-}
diff --git a/server/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java b/server/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
deleted file mode 100644
index 02b19e0..0000000
--- a/server/src/main/java/mc/server/network/netty/handler/HandshakeHandler.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package mc.server.network.netty.handler;
-
-import io.netty.channel.ChannelHandlerContext;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import mc.protocol.NetworkAttributes;
-import mc.protocol.State;
-import mc.protocol.packets.client.HandshakePacket;
-
-import javax.inject.Provider;
-
-@Slf4j
-@RequiredArgsConstructor
-public class HandshakeHandler extends AbstractPacketHandler {
-
- private final Provider statusHandlerProvider;
- private final Provider loginHandlerProvider;
- private final Provider keepAliveHandlerProvider;
-
- @Override
- protected void channelRead1(ChannelHandlerContext ctx, HandshakePacket packet) {
- log.info("{}", packet);
-
- ctx.channel().attr(NetworkAttributes.STATE).set(packet.getNextState());
-
- if (State.STATUS == packet.getNextState()) {
- ctx.pipeline().replace("handshake_handler", "status_handler", statusHandlerProvider.get());
- ctx.pipeline().addAfter("status_handler", "keepalive_handler", keepAliveHandlerProvider.get());
- } else if (State.LOGIN == packet.getNextState()) {
- ctx.channel().pipeline().replace("handshake_handler", "login_handler", loginHandlerProvider.get());
- }
- }
-}
diff --git a/server/src/main/java/mc/server/network/netty/handler/KeepAliveHandler.java b/server/src/main/java/mc/server/network/netty/handler/KeepAliveHandler.java
deleted file mode 100644
index ea69c2c..0000000
--- a/server/src/main/java/mc/server/network/netty/handler/KeepAliveHandler.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package mc.server.network.netty.handler;
-
-import io.netty.channel.ChannelHandlerContext;
-import lombok.extern.slf4j.Slf4j;
-import mc.protocol.packets.PingPacket;
-
-@Slf4j
-public class KeepAliveHandler extends AbstractPacketHandler {
-
- @Override
- protected void channelRead1(ChannelHandlerContext ctx, PingPacket packet) {
- log.info("{}", packet);
-
- ctx.writeAndFlush(packet).channel().disconnect();
- }
-}
diff --git a/server/src/main/java/mc/server/network/netty/handler/LoginHandler.java b/server/src/main/java/mc/server/network/netty/handler/LoginHandler.java
deleted file mode 100644
index 8a0d92c..0000000
--- a/server/src/main/java/mc/server/network/netty/handler/LoginHandler.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package mc.server.network.netty.handler;
-
-import io.netty.channel.ChannelHandlerContext;
-import mc.protocol.packets.client.LoginStartPacket;
-import mc.protocol.packets.server.DisconnectPacket;
-
-public class LoginHandler extends AbstractPacketHandler {
-
- @Override
- protected void channelRead1(ChannelHandlerContext ctx, LoginStartPacket packet) {
- DisconnectPacket disconnectPacket = new DisconnectPacket();
- disconnectPacket.setReason("{\n" +
- " \"text\": \"Server is not available.\"\n" +
- "}");
-
- ctx.channel().writeAndFlush(disconnectPacket).channel().disconnect();
- }
-}
diff --git a/server/src/main/java/mc/server/network/netty/handler/StatusHandler.java b/server/src/main/java/mc/server/network/netty/handler/StatusHandler.java
deleted file mode 100644
index 2fbcfe5..0000000
--- a/server/src/main/java/mc/server/network/netty/handler/StatusHandler.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package mc.server.network.netty.handler;
-
-import io.netty.channel.ChannelHandlerContext;
-import lombok.extern.slf4j.Slf4j;
-import mc.protocol.packets.client.StatusServerRequest;
-import mc.protocol.packets.server.StatusServerResponse;
-
-@Slf4j
-public class StatusHandler extends AbstractPacketHandler {
-
- @Override
- protected void channelRead1(ChannelHandlerContext ctx, StatusServerRequest packet) {
- log.info("{}", packet);
-
- StatusServerResponse response = new StatusServerResponse();
- response.setInfo("{\n" +
- " \"version\": {\n" +
- " \"name\": \"1.12.2\",\n" +
- " \"protocol\": 340\n" +
- " },\n" +
- " \"players\": {\n" +
- " \"max\": 0,\n" +
- " \"online\": 0,\n" +
- " \"sample\": []\n" +
- " },\n" +
- " \"description\": {\n" +
- " \"text\": \"Hello world\"\n" +
- " }\n" +
- "}");
-
- ctx.channel().writeAndFlush(response);
- }
-}
From 801e68ea551e2fccf98b78299bf95630e4c89f06 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Tue, 27 Apr 2021 21:32:16 +0300
Subject: [PATCH 12/34] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?=
=?UTF-8?q?=D0=B5=D0=BD=20config?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
libs.gradle | 3 +-
.../java/mc/protocol/ProtocolConstant.java | 10 +++
server/build.gradle | 2 +
server/src/main/java/mc/server/Main.java | 34 ++++++++--
.../main/java/mc/server/config/Config.java | 35 ++++++++++
.../main/java/mc/server/config/lombok.config | 1 +
.../main/java/mc/server/di/ConfigModule.java | 66 +++++++++++++++++++
.../java/mc/server/di/ServerComponent.java | 10 +++
server/src/main/resources/config.yml | 13 ++++
9 files changed, 166 insertions(+), 8 deletions(-)
create mode 100644 protocol/src/main/java/mc/protocol/ProtocolConstant.java
create mode 100644 server/src/main/java/mc/server/config/Config.java
create mode 100644 server/src/main/java/mc/server/config/lombok.config
create mode 100644 server/src/main/java/mc/server/di/ConfigModule.java
create mode 100644 server/src/main/java/mc/server/di/ServerComponent.java
create mode 100644 server/src/main/resources/config.yml
diff --git a/libs.gradle b/libs.gradle
index d6958eb..33ed495 100644
--- a/libs.gradle
+++ b/libs.gradle
@@ -14,7 +14,8 @@ ext {
guava : 'com.google.guava:guava:30.1-jre',
lang3 : 'org.apache.commons:commons-lang3:3.11',
netty : 'io.netty:netty-all:4.1.22.Final',
- reactor : 'io.projectreactor:reactor-core:3.4.5'
+ reactor : 'io.projectreactor:reactor-core:3.4.5',
+ yaml : 'org.yaml:snakeyaml:1.28'
]
libs.logger = [
diff --git a/protocol/src/main/java/mc/protocol/ProtocolConstant.java b/protocol/src/main/java/mc/protocol/ProtocolConstant.java
new file mode 100644
index 0000000..4fbbada
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/ProtocolConstant.java
@@ -0,0 +1,10 @@
+package mc.protocol;
+
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class ProtocolConstant {
+
+ public static final String PROTOCOL_NAME = "1.12.2";
+ public static final int PROTOCOL_NUMBER = 340;
+}
diff --git a/server/build.gradle b/server/build.gradle
index 491cc7b..46c8b98 100644
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -3,6 +3,7 @@
gradle :server:run
*/
+//file:noinspection GrUnresolvedAccess
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
apply plugin: 'application'
@@ -18,4 +19,5 @@ dependencies {
implementation libs.netty
implementation libs.reactor
implementation libs.guava
+ implementation libs.yaml
}
diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
index d0a445b..7736a56 100644
--- a/server/src/main/java/mc/server/Main.java
+++ b/server/src/main/java/mc/server/Main.java
@@ -2,18 +2,38 @@ package mc.server;
import lombok.extern.slf4j.Slf4j;
import mc.protocol.NettyServer;
+import mc.protocol.ProtocolConstant;
import mc.protocol.packets.PingPacket;
import mc.protocol.packets.client.HandshakePacket;
import mc.protocol.packets.client.LoginStartPacket;
import mc.protocol.packets.client.StatusServerRequest;
import mc.protocol.packets.server.DisconnectPacket;
import mc.protocol.packets.server.StatusServerResponse;
+import mc.server.config.Config;
+import mc.server.di.ConfigModule;
+import mc.server.di.DaggerServerComponent;
+import mc.server.di.ServerComponent;
+
+import java.nio.file.Paths;
@Slf4j
public class Main {
public static void main(String[] args) {
- log.info("hello");
+ log.info("mc-project launch");
+
+ ConfigModule configModule;
+ if (args.length > 0) {
+ configModule = new ConfigModule(Paths.get(args[0]));
+ } else {
+ configModule = new ConfigModule(Paths.get("config.yml"));
+ }
+
+ ServerComponent serverComponent = DaggerServerComponent.builder()
+ .configModule(configModule)
+ .build();
+
+ Config config = serverComponent.getConfig();
NettyServer server = NettyServer.createServer();
@@ -31,16 +51,16 @@ public class Main {
StatusServerResponse response = new StatusServerResponse();
response.setInfo("{\n" +
" \"version\": {\n" +
- " \"name\": \"1.12.2\",\n" +
- " \"protocol\": 340\n" +
+ " \"name\": \"" + ProtocolConstant.PROTOCOL_NAME + "\",\n" +
+ " \"protocol\": " + ProtocolConstant.PROTOCOL_NUMBER + "\n" +
" },\n" +
" \"players\": {\n" +
- " \"max\": 0,\n" +
- " \"online\": 0,\n" +
+ " \"max\": " + config.players().maxOnlile() + ",\n" +
+ " \"online\": " + config.players().onlile() + ",\n" +
" \"sample\": []\n" +
" },\n" +
" \"description\": {\n" +
- " \"text\": \"Hello world\"\n" +
+ " \"text\": \"" + config.motd() + "\"\n" +
" }\n" +
"}");
@@ -58,6 +78,6 @@ public class Main {
channel.getCtx().writeAndFlush(disconnectPacket).channel().disconnect();
});
- server.bind("127.0.0.1", 25565);
+ server.bind(config.server().host(), config.server().port());
}
}
diff --git a/server/src/main/java/mc/server/config/Config.java b/server/src/main/java/mc/server/config/Config.java
new file mode 100644
index 0000000..f8f5f14
--- /dev/null
+++ b/server/src/main/java/mc/server/config/Config.java
@@ -0,0 +1,35 @@
+package mc.server.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.nio.file.Path;
+
+@Getter
+@Setter
+@ToString
+public class Config {
+
+ private final Server server = new Server();
+ private final Players players = new Players();
+
+ private String motd;
+ private Path iconPath;
+
+ @Getter
+ @Setter
+ @ToString
+ public static class Server {
+ private String host;
+ private int port;
+ }
+
+ @Getter
+ @Setter
+ @ToString
+ public static class Players {
+ private int maxOnlile;
+ private int onlile;
+ }
+}
diff --git a/server/src/main/java/mc/server/config/lombok.config b/server/src/main/java/mc/server/config/lombok.config
new file mode 100644
index 0000000..f4387a7
--- /dev/null
+++ b/server/src/main/java/mc/server/config/lombok.config
@@ -0,0 +1 @@
+lombok.accessors.fluent=true
\ No newline at end of file
diff --git a/server/src/main/java/mc/server/di/ConfigModule.java b/server/src/main/java/mc/server/di/ConfigModule.java
new file mode 100644
index 0000000..510b077
--- /dev/null
+++ b/server/src/main/java/mc/server/di/ConfigModule.java
@@ -0,0 +1,66 @@
+package mc.server.di;
+
+import dagger.Module;
+import dagger.Provides;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import mc.server.config.Config;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map;
+
+@Slf4j
+@Module
+@RequiredArgsConstructor
+public class ConfigModule {
+
+ private final Path configPath;
+
+ @Provides
+ Config provideConfig() {
+ Config config = new Config();
+ Map map = new Yaml().load(readConfigAsString());
+
+ config.server().host(fromYamlPath("server/host", map, "127.0.0.1"));
+ config.server().port(fromYamlPath("server/port", map, 25565));
+ config.motd(fromYamlPath("motd", map, ""));
+ config.players().maxOnlile(fromYamlPath("players/max-online", map, 0));
+ config.players().onlile(fromYamlPath("players/online", map, 0));
+
+ if (Boolean.TRUE.equals(fromYamlPath("icon/enable", map, false))) {
+ config.iconPath(Paths.get(fromYamlPath("icon/path", map, "favicon.png")));
+ }
+
+ map.clear();
+ return config;
+ }
+
+ private String readConfigAsString() {
+ try {
+ return Files.readString(configPath);
+ } catch (IOException e) {
+ log.error("Can't load config from '{}'", configPath.toAbsolutePath(), e);
+ return "";
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static T fromYamlPath(String mapPath, Map map, T defaultValue) {
+ String[] keys = mapPath.split("/", 2);
+
+ if (map.containsKey(keys[0])) {
+ Object object = map.get(keys[0]);
+ if (keys.length > 1) {
+ return fromYamlPath(keys[1], (Map) object, defaultValue);
+ } else {
+ return (T) object;
+ }
+ } else {
+ return defaultValue;
+ }
+ }
+}
diff --git a/server/src/main/java/mc/server/di/ServerComponent.java b/server/src/main/java/mc/server/di/ServerComponent.java
new file mode 100644
index 0000000..4147205
--- /dev/null
+++ b/server/src/main/java/mc/server/di/ServerComponent.java
@@ -0,0 +1,10 @@
+package mc.server.di;
+
+import dagger.Component;
+import mc.server.config.Config;
+
+@Component(modules = ConfigModule.class)
+public interface ServerComponent {
+
+ Config getConfig();
+}
diff --git a/server/src/main/resources/config.yml b/server/src/main/resources/config.yml
new file mode 100644
index 0000000..af6b6aa
--- /dev/null
+++ b/server/src/main/resources/config.yml
@@ -0,0 +1,13 @@
+server:
+ host: 127.0.0.1
+ port: 25565
+
+motd: 'mc-project::ZERO'
+
+players:
+ max-online: 0
+ online: 0
+
+icon:
+ enable: false
+ path: favicon.png
\ No newline at end of file
From f4f796c3a424ef3e8a41203524702af1984ad9ca Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Wed, 28 Apr 2021 18:34:19 +0300
Subject: [PATCH 13/34] =?UTF-8?q?=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB?=
=?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=B0=20=D1=81=D0=B5=D1=80?=
=?UTF-8?q?=D0=B2=D0=B5=D1=80=D0=BD=D1=8B=D0=B5=20=D0=B8=20=D0=BA=D0=BB?=
=?UTF-8?q?=D0=B8=D0=B5=D0=BD=D1=82=D1=81=D0=BA=D0=B8=D0=B5=20=D0=BF=D0=B0?=
=?UTF-8?q?=D0=BA=D0=B5=D1=82=D1=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
protocol/src/main/java/mc/protocol/State.java | 59 ++++++++-----------
.../java/mc/protocol/di/ProtocolModule.java | 2 +-
.../mc/protocol/io/codec/ProtocolDecoder.java | 7 +--
.../mc/protocol/io/codec/ProtocolEncoder.java | 9 ++-
.../mc/protocol/packets/ClientSidePacket.java | 11 ++++
.../java/mc/protocol/packets/EmptyPacket.java | 2 +-
.../main/java/mc/protocol/packets/Packet.java | 5 --
.../mc/protocol/packets/PacketDirection.java | 6 --
.../java/mc/protocol/packets/PingPacket.java | 2 +-
.../mc/protocol/packets/ServerSidePacket.java | 11 ++++
.../mc/protocol/packets/UnknownPacket.java | 7 +--
.../packets/client/HandshakePacket.java | 11 +---
.../packets/client/LoginStartPacket.java | 8 +--
...st.java => StatusServerRequestPacket.java} | 2 +-
.../packets/server/DisconnectPacket.java | 9 +--
...e.java => StatusServerResponsePacket.java} | 9 +--
server/src/main/java/mc/server/Main.java | 8 +--
17 files changed, 72 insertions(+), 96 deletions(-)
create mode 100644 protocol/src/main/java/mc/protocol/packets/ClientSidePacket.java
delete mode 100644 protocol/src/main/java/mc/protocol/packets/PacketDirection.java
create mode 100644 protocol/src/main/java/mc/protocol/packets/ServerSidePacket.java
rename protocol/src/main/java/mc/protocol/packets/client/{StatusServerRequest.java => StatusServerRequestPacket.java} (86%)
rename protocol/src/main/java/mc/protocol/packets/server/{StatusServerResponse.java => StatusServerResponsePacket.java} (88%)
diff --git a/protocol/src/main/java/mc/protocol/State.java b/protocol/src/main/java/mc/protocol/State.java
index 01c2971..0190377 100644
--- a/protocol/src/main/java/mc/protocol/State.java
+++ b/protocol/src/main/java/mc/protocol/State.java
@@ -1,44 +1,45 @@
package mc.protocol;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.ImmutableBiMap;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import mc.protocol.packets.ClientSidePacket;
import mc.protocol.packets.Packet;
-import mc.protocol.packets.PacketDirection;
import mc.protocol.packets.PingPacket;
+import mc.protocol.packets.ServerSidePacket;
import mc.protocol.packets.client.HandshakePacket;
import mc.protocol.packets.client.LoginStartPacket;
-import mc.protocol.packets.client.StatusServerRequest;
+import mc.protocol.packets.client.StatusServerRequestPacket;
import mc.protocol.packets.server.DisconnectPacket;
-import mc.protocol.packets.server.StatusServerResponse;
+import mc.protocol.packets.server.StatusServerResponsePacket;
import javax.annotation.Nullable;
+import java.util.Collections;
+import java.util.Map;
@RequiredArgsConstructor
public enum State {
HANDSHAKING(-1,
- // server bound
- ImmutableBiMap.of(0x00, HandshakePacket.class)
+ // client side
+ Map.of(0x00, HandshakePacket.class)
),
STATUS(1,
- // server bound
- ImmutableBiMap.of(
- 0x00, StatusServerRequest.class,
+ // client side
+ Map.of(
+ 0x00, StatusServerRequestPacket.class,
0x01, PingPacket.class
),
- // client bound
- ImmutableBiMap.of(
- 0x00, StatusServerResponse.class,
- 0x01, PingPacket.class
+ // server side
+ Map.of(
+ StatusServerResponsePacket.class, 0x00,
+ PingPacket.class, 0x01
)
),
LOGIN(2,
// server bound
- ImmutableBiMap.of(0x00, LoginStartPacket.class),
+ Map.of(0x00, LoginStartPacket.class),
// client bound
- ImmutableBiMap.of(0x00, DisconnectPacket.class)
+ Map.of(DisconnectPacket.class, 0x00)
);
@Nullable
@@ -56,30 +57,22 @@ public enum State {
private final int id;
@Getter
- private final BiMap> serverBoundPackets;
- private final BiMap> clientBoundPackets;
+ private final Map> clientSidePackets;
+ private final Map, Integer> serverSidePackets;
- State(int id, BiMap> serverBoundPackets) {
+ State(int id, Map> clientSidePackets) {
this.id = id;
- this.serverBoundPackets = serverBoundPackets;
- this.clientBoundPackets = ImmutableBiMap.of();
+ this.clientSidePackets = clientSidePackets;
+ this.serverSidePackets = Collections.emptyMap();
}
@Nullable
- public Class extends Packet> getPacketById(PacketDirection direction, int id) {
- if (PacketDirection.CLIENT_BOUND == direction) {
- return clientBoundPackets == null ? null : clientBoundPackets.get(id);
- } else {
- return serverBoundPackets == null ? null : serverBoundPackets.get(id);
- }
+ public Class extends ClientSidePacket> getClientSidePacketById(int id) {
+ return clientSidePackets == null ? null : clientSidePackets.get(id);
}
@Nullable
- public Integer getIdByPacket(PacketDirection direction, Class extends Packet> clazz) {
- if (PacketDirection.CLIENT_BOUND == direction) {
- return clientBoundPackets == null ? null : clientBoundPackets.inverse().get(clazz);
- } else {
- return serverBoundPackets == null ? null : serverBoundPackets.inverse().get(clazz);
- }
+ public Integer getServerSidePacketId(Class extends Packet> clazz) {
+ return serverSidePackets == null ? null : serverSidePackets.get(clazz);
}
}
diff --git a/protocol/src/main/java/mc/protocol/di/ProtocolModule.java b/protocol/src/main/java/mc/protocol/di/ProtocolModule.java
index 3ee3ba3..479e6c9 100644
--- a/protocol/src/main/java/mc/protocol/di/ProtocolModule.java
+++ b/protocol/src/main/java/mc/protocol/di/ProtocolModule.java
@@ -84,7 +84,7 @@ public class ProtocolModule {
ImmutableMap.Builder, Sinks.Many> builder = ImmutableMap.builder();
Stream.of(State.values())
- .flatMap(state -> state.getServerBoundPackets().values().stream())
+ .flatMap(state -> state.getClientSidePackets().values().stream())
.forEach(packetClass -> builder.put(packetClass, Sinks.many().multicast().directBestEffort()));
return builder.build();
diff --git a/protocol/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java b/protocol/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java
index a59f5a0..58d22d7 100644
--- a/protocol/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java
+++ b/protocol/src/main/java/mc/protocol/io/codec/ProtocolDecoder.java
@@ -8,8 +8,7 @@ import lombok.extern.slf4j.Slf4j;
import mc.protocol.NetworkAttributes;
import mc.protocol.State;
import mc.protocol.io.NetByteBuf;
-import mc.protocol.packets.Packet;
-import mc.protocol.packets.PacketDirection;
+import mc.protocol.packets.ClientSidePacket;
import mc.protocol.packets.UnknownPacket;
import java.util.List;
@@ -39,7 +38,7 @@ public class ProtocolDecoder extends ByteToMessageDecoder {
NetByteBuf netByteBuf = new NetByteBuf(in);
int packetId = netByteBuf.readVarInt();
- Class extends Packet> packetClass = state.getPacketById(PacketDirection.SERVER_BOUND, packetId);
+ Class extends ClientSidePacket> packetClass = state.getClientSidePacketById(packetId);
if (packetClass == null) {
log.warn("Unkown packet: State {} ; Id {}", state, packetId);
@@ -51,7 +50,7 @@ public class ProtocolDecoder extends ByteToMessageDecoder {
netByteBuf.skipBytes(netByteBuf.readableBytes());
}
} else {
- Packet packet = packetClass.getDeclaredConstructor().newInstance();
+ ClientSidePacket packet = packetClass.getDeclaredConstructor().newInstance();
packet.readSelf(netByteBuf);
out.add(packet);
}
diff --git a/protocol/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java b/protocol/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java
index d26f26c..418d3ff 100644
--- a/protocol/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java
+++ b/protocol/src/main/java/mc/protocol/io/codec/ProtocolEncoder.java
@@ -7,17 +7,16 @@ import io.netty.handler.codec.MessageToByteEncoder;
import mc.protocol.NetworkAttributes;
import mc.protocol.State;
import mc.protocol.io.NetByteBuf;
-import mc.protocol.packets.Packet;
-import mc.protocol.packets.PacketDirection;
+import mc.protocol.packets.ServerSidePacket;
import java.util.Objects;
-public class ProtocolEncoder extends MessageToByteEncoder {
+public class ProtocolEncoder extends MessageToByteEncoder {
@Override
- protected void encode(ChannelHandlerContext ctx, Packet packet, ByteBuf out) {
+ protected void encode(ChannelHandlerContext ctx, ServerSidePacket packet, ByteBuf out) {
State state = ctx.channel().attr(NetworkAttributes.STATE).get();
- int packetId = Objects.requireNonNull(state.getIdByPacket(PacketDirection.CLIENT_BOUND, packet.getClass()));
+ int packetId = Objects.requireNonNull(state.getServerSidePacketId(packet.getClass()));
NetByteBuf buffer = new NetByteBuf(Unpooled.buffer());
buffer.writeVarInt(packetId);
diff --git a/protocol/src/main/java/mc/protocol/packets/ClientSidePacket.java b/protocol/src/main/java/mc/protocol/packets/ClientSidePacket.java
new file mode 100644
index 0000000..6629750
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/packets/ClientSidePacket.java
@@ -0,0 +1,11 @@
+package mc.protocol.packets;
+
+import mc.protocol.io.NetByteBuf;
+
+/**
+ * Пакеты отправляемые клиентом.
+ */
+public interface ClientSidePacket extends Packet {
+
+ void readSelf(NetByteBuf netByteBuf);
+}
diff --git a/protocol/src/main/java/mc/protocol/packets/EmptyPacket.java b/protocol/src/main/java/mc/protocol/packets/EmptyPacket.java
index b6dd02f..60c800f 100644
--- a/protocol/src/main/java/mc/protocol/packets/EmptyPacket.java
+++ b/protocol/src/main/java/mc/protocol/packets/EmptyPacket.java
@@ -2,7 +2,7 @@ package mc.protocol.packets;
import mc.protocol.io.NetByteBuf;
-public abstract class EmptyPacket implements Packet {
+public abstract class EmptyPacket implements ClientSidePacket, ServerSidePacket {
@Override
public void readSelf(NetByteBuf netByteBuf) {
diff --git a/protocol/src/main/java/mc/protocol/packets/Packet.java b/protocol/src/main/java/mc/protocol/packets/Packet.java
index 95e1385..02ce207 100644
--- a/protocol/src/main/java/mc/protocol/packets/Packet.java
+++ b/protocol/src/main/java/mc/protocol/packets/Packet.java
@@ -1,7 +1,5 @@
package mc.protocol.packets;
-import mc.protocol.io.NetByteBuf;
-
/**
* Пакет.
*
@@ -18,7 +16,4 @@ import mc.protocol.io.NetByteBuf;
*/
public interface Packet {
- void readSelf(NetByteBuf netByteBuf);
-
- void writeSelf(NetByteBuf netByteBuf);
}
diff --git a/protocol/src/main/java/mc/protocol/packets/PacketDirection.java b/protocol/src/main/java/mc/protocol/packets/PacketDirection.java
deleted file mode 100644
index 2760689..0000000
--- a/protocol/src/main/java/mc/protocol/packets/PacketDirection.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package mc.protocol.packets;
-
-public enum PacketDirection {
-
- SERVER_BOUND, CLIENT_BOUND
-}
diff --git a/protocol/src/main/java/mc/protocol/packets/PingPacket.java b/protocol/src/main/java/mc/protocol/packets/PingPacket.java
index 81e0b88..f40b121 100644
--- a/protocol/src/main/java/mc/protocol/packets/PingPacket.java
+++ b/protocol/src/main/java/mc/protocol/packets/PingPacket.java
@@ -25,7 +25,7 @@ import mc.protocol.io.NetByteBuf;
* @see Keep Alive
*/
@Data
-public class PingPacket implements Packet {
+public class PingPacket implements ClientSidePacket, ServerSidePacket {
private Long payload;
diff --git a/protocol/src/main/java/mc/protocol/packets/ServerSidePacket.java b/protocol/src/main/java/mc/protocol/packets/ServerSidePacket.java
new file mode 100644
index 0000000..086deb6
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/packets/ServerSidePacket.java
@@ -0,0 +1,11 @@
+package mc.protocol.packets;
+
+import mc.protocol.io.NetByteBuf;
+
+/**
+ * Пакеты отправляемые сервером.
+ */
+public interface ServerSidePacket extends Packet {
+
+ void writeSelf(NetByteBuf netByteBuf);
+}
diff --git a/protocol/src/main/java/mc/protocol/packets/UnknownPacket.java b/protocol/src/main/java/mc/protocol/packets/UnknownPacket.java
index 04b4873..aef7b74 100644
--- a/protocol/src/main/java/mc/protocol/packets/UnknownPacket.java
+++ b/protocol/src/main/java/mc/protocol/packets/UnknownPacket.java
@@ -7,7 +7,7 @@ import mc.protocol.io.NetByteBuf;
@Data
@ToString(exclude = "rawData")
-public class UnknownPacket implements Packet {
+public class UnknownPacket implements ClientSidePacket {
private final State state;
private final int id;
@@ -19,9 +19,4 @@ public class UnknownPacket implements Packet {
rawData = new byte[dataSize];
netByteBuf.readBytes(rawData);
}
-
- @Override
- public void writeSelf(NetByteBuf netByteBuf) {
- netByteBuf.writeBytes(rawData);
- }
}
diff --git a/protocol/src/main/java/mc/protocol/packets/client/HandshakePacket.java b/protocol/src/main/java/mc/protocol/packets/client/HandshakePacket.java
index eb786bc..ccb86b5 100644
--- a/protocol/src/main/java/mc/protocol/packets/client/HandshakePacket.java
+++ b/protocol/src/main/java/mc/protocol/packets/client/HandshakePacket.java
@@ -6,7 +6,7 @@ import lombok.NoArgsConstructor;
import lombok.ToString;
import mc.protocol.State;
import mc.protocol.io.NetByteBuf;
-import mc.protocol.packets.Packet;
+import mc.protocol.packets.ClientSidePacket;
/**
* Handshake packet.
@@ -32,7 +32,7 @@ import mc.protocol.packets.Packet;
@Getter
@EqualsAndHashCode
@ToString
-public class HandshakePacket implements Packet {
+public class HandshakePacket implements ClientSidePacket {
private int protocolVersion;
private String host;
@@ -47,11 +47,4 @@ public class HandshakePacket implements Packet {
nextState = State.getById(netByteBuf.readVarInt());
}
- @Override
- public void writeSelf(NetByteBuf netByteBuf) {
- netByteBuf.writeVarInt(protocolVersion);
- netByteBuf.writeString(host);
- netByteBuf.writeShort(port);
- netByteBuf.writeVarInt(nextState.getId());
- }
}
diff --git a/protocol/src/main/java/mc/protocol/packets/client/LoginStartPacket.java b/protocol/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
index 75ebe04..77775b6 100644
--- a/protocol/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
+++ b/protocol/src/main/java/mc/protocol/packets/client/LoginStartPacket.java
@@ -5,7 +5,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import mc.protocol.io.NetByteBuf;
-import mc.protocol.packets.Packet;
+import mc.protocol.packets.ClientSidePacket;
/**
* Login start packet.
@@ -25,7 +25,7 @@ import mc.protocol.packets.Packet;
@Getter
@EqualsAndHashCode
@ToString
-public class LoginStartPacket implements Packet {
+public class LoginStartPacket implements ClientSidePacket {
private String name;
@@ -34,8 +34,4 @@ public class LoginStartPacket implements Packet {
this.name = netByteBuf.readString();
}
- @Override
- public void writeSelf(NetByteBuf netByteBuf) {
- netByteBuf.writeString(name);
- }
}
diff --git a/protocol/src/main/java/mc/protocol/packets/client/StatusServerRequest.java b/protocol/src/main/java/mc/protocol/packets/client/StatusServerRequestPacket.java
similarity index 86%
rename from protocol/src/main/java/mc/protocol/packets/client/StatusServerRequest.java
rename to protocol/src/main/java/mc/protocol/packets/client/StatusServerRequestPacket.java
index 9cd1e61..5f4e84c 100644
--- a/protocol/src/main/java/mc/protocol/packets/client/StatusServerRequest.java
+++ b/protocol/src/main/java/mc/protocol/packets/client/StatusServerRequestPacket.java
@@ -13,6 +13,6 @@ import mc.protocol.packets.EmptyPacket;
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
@ToString
-public class StatusServerRequest extends EmptyPacket {
+public class StatusServerRequestPacket extends EmptyPacket {
}
diff --git a/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java b/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
index 2cfb3e2..dca7fef 100644
--- a/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
+++ b/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
@@ -3,7 +3,7 @@ package mc.protocol.packets.server;
import lombok.Data;
import mc.protocol.State;
import mc.protocol.io.NetByteBuf;
-import mc.protocol.packets.Packet;
+import mc.protocol.packets.ServerSidePacket;
/**
* Diconnect packet.
@@ -21,7 +21,7 @@ import mc.protocol.packets.Packet;
* @see State
*/
@Data
-public class DisconnectPacket implements Packet {
+public class DisconnectPacket implements ServerSidePacket {
/**
* Причина отключения.
@@ -35,11 +35,6 @@ public class DisconnectPacket implements Packet {
*/
private String reason;
- @Override
- public void readSelf(NetByteBuf netByteBuf) {
- this.reason = netByteBuf.readString();
- }
-
@Override
public void writeSelf(NetByteBuf netByteBuf) {
netByteBuf.writeString(reason);
diff --git a/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java b/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponsePacket.java
similarity index 88%
rename from protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
rename to protocol/src/main/java/mc/protocol/packets/server/StatusServerResponsePacket.java
index 8cf99f4..fd6b4ef 100644
--- a/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
+++ b/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponsePacket.java
@@ -2,7 +2,7 @@ package mc.protocol.packets.server;
import lombok.Data;
import mc.protocol.io.NetByteBuf;
-import mc.protocol.packets.Packet;
+import mc.protocol.packets.ServerSidePacket;
/**
* Status server packet, response.
@@ -19,7 +19,7 @@ import mc.protocol.packets.Packet;
*
*/
@Data
-public class StatusServerResponse implements Packet {
+public class StatusServerResponsePacket implements ServerSidePacket {
/**
* Информация о серере в формате JSON
@@ -50,11 +50,6 @@ public class StatusServerResponse implements Packet {
*/
private String info;
- @Override
- public void readSelf(NetByteBuf netByteBuf) {
- info = netByteBuf.readString();
- }
-
@Override
public void writeSelf(NetByteBuf netByteBuf) {
netByteBuf.writeString(info);
diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
index 7736a56..156aceb 100644
--- a/server/src/main/java/mc/server/Main.java
+++ b/server/src/main/java/mc/server/Main.java
@@ -6,9 +6,9 @@ import mc.protocol.ProtocolConstant;
import mc.protocol.packets.PingPacket;
import mc.protocol.packets.client.HandshakePacket;
import mc.protocol.packets.client.LoginStartPacket;
-import mc.protocol.packets.client.StatusServerRequest;
+import mc.protocol.packets.client.StatusServerRequestPacket;
import mc.protocol.packets.server.DisconnectPacket;
-import mc.protocol.packets.server.StatusServerResponse;
+import mc.protocol.packets.server.StatusServerResponsePacket;
import mc.server.config.Config;
import mc.server.di.ConfigModule;
import mc.server.di.DaggerServerComponent;
@@ -45,10 +45,10 @@ public class Main {
.doOnNext(channel -> log.info("{}", channel.getPacket()))
.subscribe(channel -> channel.getCtx().writeAndFlush(channel.getPacket()).channel().disconnect());
- server.packetFlux(StatusServerRequest.class)
+ server.packetFlux(StatusServerRequestPacket.class)
.doOnNext(channel -> log.info("{}", channel.getPacket()))
.subscribe(channel -> {
- StatusServerResponse response = new StatusServerResponse();
+ StatusServerResponsePacket response = new StatusServerResponsePacket();
response.setInfo("{\n" +
" \"version\": {\n" +
" \"name\": \"" + ProtocolConstant.PROTOCOL_NAME + "\",\n" +
From 09a3d16b772fdd4ac8641651ea5749a62779e8f2 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Wed, 28 Apr 2021 18:47:31 +0300
Subject: [PATCH 14/34] =?UTF-8?q?JSON=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82?=
=?UTF-8?q?=D0=BE=20String?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
libs.gradle | 3 +-
protocol/build.gradle | 1 +
protocol/src/main/java/mc/protocol/State.java | 4 +-
.../java/mc/protocol/model/ServerInfo.java | 47 ++++++++++
.../main/java/mc/protocol/model/lombok.config | 1 +
.../packets/server/DisconnectPacket.java | 23 ++---
.../packets/server/StatusServerResponse.java | 92 +++++++++++++++++++
.../server/StatusServerResponsePacket.java | 57 ------------
server/src/main/java/mc/server/Main.java | 33 +++----
9 files changed, 171 insertions(+), 90 deletions(-)
create mode 100644 protocol/src/main/java/mc/protocol/model/ServerInfo.java
create mode 100644 protocol/src/main/java/mc/protocol/model/lombok.config
create mode 100644 protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
delete mode 100644 protocol/src/main/java/mc/protocol/packets/server/StatusServerResponsePacket.java
diff --git a/libs.gradle b/libs.gradle
index 33ed495..fc2589b 100644
--- a/libs.gradle
+++ b/libs.gradle
@@ -15,7 +15,8 @@ ext {
lang3 : 'org.apache.commons:commons-lang3:3.11',
netty : 'io.netty:netty-all:4.1.22.Final',
reactor : 'io.projectreactor:reactor-core:3.4.5',
- yaml : 'org.yaml:snakeyaml:1.28'
+ yaml : 'org.yaml:snakeyaml:1.28',
+ json : 'com.eclipsesource.minimal-json:minimal-json:0.9.5'
]
libs.logger = [
diff --git a/protocol/build.gradle b/protocol/build.gradle
index 4677d8a..1a4110a 100644
--- a/protocol/build.gradle
+++ b/protocol/build.gradle
@@ -4,6 +4,7 @@ dependencies {
implementation libs.netty
implementation libs.reactor
implementation libs.guava
+ implementation libs.json
testImplementation libs.lang3
}
diff --git a/protocol/src/main/java/mc/protocol/State.java b/protocol/src/main/java/mc/protocol/State.java
index 0190377..b849adf 100644
--- a/protocol/src/main/java/mc/protocol/State.java
+++ b/protocol/src/main/java/mc/protocol/State.java
@@ -10,7 +10,7 @@ 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.StatusServerResponsePacket;
+import mc.protocol.packets.server.StatusServerResponse;
import javax.annotation.Nullable;
import java.util.Collections;
@@ -31,7 +31,7 @@ public enum State {
),
// server side
Map.of(
- StatusServerResponsePacket.class, 0x00,
+ StatusServerResponse.class, 0x00,
PingPacket.class, 0x01
)
),
diff --git a/protocol/src/main/java/mc/protocol/model/ServerInfo.java b/protocol/src/main/java/mc/protocol/model/ServerInfo.java
new file mode 100644
index 0000000..002d52b
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/model/ServerInfo.java
@@ -0,0 +1,47 @@
+package mc.protocol.model;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.RequiredArgsConstructor;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+@Getter
+@Setter
+@ToString
+public class ServerInfo {
+
+ private final Version version = new Version();
+ private final Players players = new Players();
+
+ private String description;
+ private String favicon;
+
+ @Getter
+ @Setter
+ @ToString
+ public static class Version {
+ private String name;
+ private int protocol;
+ }
+
+ @Getter
+ @Setter
+ @ToString
+ public static class Players {
+ private int max;
+ private int online;
+ private List sample;
+ }
+
+ @RequiredArgsConstructor
+ @Getter
+ @EqualsAndHashCode
+ @ToString
+ public static class SamplePlayer {
+ private final String id;
+ private final String name;
+ }
+}
diff --git a/protocol/src/main/java/mc/protocol/model/lombok.config b/protocol/src/main/java/mc/protocol/model/lombok.config
new file mode 100644
index 0000000..f4387a7
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/model/lombok.config
@@ -0,0 +1 @@
+lombok.accessors.fluent=true
\ No newline at end of file
diff --git a/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java b/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
index dca7fef..c45891c 100644
--- a/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
+++ b/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
@@ -1,5 +1,6 @@
package mc.protocol.packets.server;
+import com.eclipsesource.json.Json;
import lombok.Data;
import mc.protocol.State;
import mc.protocol.io.NetByteBuf;
@@ -12,9 +13,16 @@ import mc.protocol.packets.ServerSidePacket;
*
* Структура пакета
*
- * | FIELD | TYPE | NOTES |
- * |--------|------|----------------------------------|
- * | Reason | Text | Причина отключения. Опционально. |
+ * | FIELD | TYPE | NOTES |
+ * |-------------|--------|----------------------------------|
+ * | JSON Reason | String | Причина отключения. Опционально. |
+ *
+ *
+ * Пример JSON Reason
+ *
+ * {
+ * "text": "foo"
+ * }
*
*
* @see Disconnect
@@ -25,18 +33,11 @@ public class DisconnectPacket implements ServerSidePacket {
/**
* Причина отключения.
- *
- * Пример:
- *
- * {
- * "text": "foo"
- * }
- *
*/
private String reason;
@Override
public void writeSelf(NetByteBuf netByteBuf) {
- netByteBuf.writeString(reason);
+ netByteBuf.writeString(Json.object().add("text", reason).toString());
}
}
diff --git a/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java b/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
new file mode 100644
index 0000000..a238d20
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
@@ -0,0 +1,92 @@
+package mc.protocol.packets.server;
+
+import com.eclipsesource.json.Json;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.Streams;
+import lombok.Data;
+import mc.protocol.io.NetByteBuf;
+import mc.protocol.model.ServerInfo;
+import mc.protocol.packets.ServerSidePacket;
+
+import java.util.stream.Collector;
+
+/**
+ * Status server packet, response.
+ *
+ * Информация о сервере
+ *
+ * Структура пакета
+ *
+ * | FIELD | TYPE | NOTES |
+ * |---------------|--------|-----------------------------------------|
+ * | JSON Response | String | Информация о сервере в JSON формате [1] |
+ *
+ * [1] - Server List Ping: Response
+ *
+ *
+ * Пример JSON Response
+ *
+ * {
+ * "version": {
+ * "name": "1.8.7",
+ * "protocol": 47
+ * },
+ * "players": {
+ * "max": 100,
+ * "online": 5,
+ * "sample": [
+ * {
+ * "name": "thinkofdeath",
+ * "id": "4566e69f-c907-48ee-8d71-d7ba5aa00d20"
+ * }
+ * ]
+ * },
+ * "description": {
+ * "text": "Hello world"
+ * },
+ * "favicon": "data:image/png;base64,<data>"
+ * }
+ *
+ */
+@Data
+public class StatusServerResponse implements ServerSidePacket {
+
+ /**
+ * Информация о серере.
+ */
+ private ServerInfo info;
+
+ @Override
+ public void writeSelf(NetByteBuf netByteBuf) {
+ netByteBuf.writeString(Json.object()
+ .add("version", createVersionObj())
+ .add("players", createPlayersObj())
+ .add("description", Json.object().add("text", info.description()))
+ .toString());
+ }
+
+ private JsonObject createVersionObj() {
+ return Json.object()
+ .add("name", info.version().name())
+ .add("protocol", info.version().protocol());
+ }
+
+ private JsonObject createPlayersObj() {
+ JsonArray sampleArr = info.players().sample().stream()
+ .map(samplePlayer -> Json.object()
+ .add("name", samplePlayer.name())
+ .add("id", samplePlayer.id()))
+ .collect(Collector.of(Json::array, JsonArray::add, StatusServerResponse::jsonArrayAddAll));
+
+ return Json.object()
+ .add("max", info.players().max())
+ .add("online", info.players().online())
+ .add("sample", sampleArr);
+ }
+
+ private static JsonArray jsonArrayAddAll(JsonArray jsonArrayTo, JsonArray jsonArrayFrom) {
+ Streams.stream(jsonArrayFrom).forEach(jsonArrayTo::add);
+ return jsonArrayTo;
+ }
+}
diff --git a/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponsePacket.java b/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponsePacket.java
deleted file mode 100644
index fd6b4ef..0000000
--- a/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponsePacket.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package mc.protocol.packets.server;
-
-import lombok.Data;
-import mc.protocol.io.NetByteBuf;
-import mc.protocol.packets.ServerSidePacket;
-
-/**
- * Status server packet, response.
- *
- * Информация о сервере
- *
- * Структура пакета
- *
- * | FIELD | TYPE | NOTES |
- * |---------------|--------|-----------------------------------------|
- * | JSON Response | String | Информация о сервере в JSON формате [1] |
- *
- * [1] - Server List Ping: Response
- *
- */
-@Data
-public class StatusServerResponsePacket implements ServerSidePacket {
-
- /**
- * Информация о серере в формате JSON
- *
- * Пример
- *
- * {
- * "version": {
- * "name": "1.8.7",
- * "protocol": 47
- * },
- * "players": {
- * "max": 100,
- * "online": 5,
- * "sample": [
- * {
- * "name": "thinkofdeath",
- * "id": "4566e69f-c907-48ee-8d71-d7ba5aa00d20"
- * }
- * ]
- * },
- * "description": {
- * "text": "Hello world"
- * },
- * "favicon": "data:image/png;base64,<data>"
- * }
- *
- */
- private String info;
-
- @Override
- public void writeSelf(NetByteBuf netByteBuf) {
- netByteBuf.writeString(info);
- }
-}
diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
index 156aceb..0592fa1 100644
--- a/server/src/main/java/mc/server/Main.java
+++ b/server/src/main/java/mc/server/Main.java
@@ -3,18 +3,20 @@ package mc.server;
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.StatusServerResponsePacket;
+import mc.protocol.packets.server.StatusServerResponse;
import mc.server.config.Config;
import mc.server.di.ConfigModule;
import mc.server.di.DaggerServerComponent;
import mc.server.di.ServerComponent;
import java.nio.file.Paths;
+import java.util.Collections;
@Slf4j
public class Main {
@@ -48,21 +50,16 @@ public class Main {
server.packetFlux(StatusServerRequestPacket.class)
.doOnNext(channel -> log.info("{}", channel.getPacket()))
.subscribe(channel -> {
- StatusServerResponsePacket response = new StatusServerResponsePacket();
- response.setInfo("{\n" +
- " \"version\": {\n" +
- " \"name\": \"" + ProtocolConstant.PROTOCOL_NAME + "\",\n" +
- " \"protocol\": " + ProtocolConstant.PROTOCOL_NUMBER + "\n" +
- " },\n" +
- " \"players\": {\n" +
- " \"max\": " + config.players().maxOnlile() + ",\n" +
- " \"online\": " + config.players().onlile() + ",\n" +
- " \"sample\": []\n" +
- " },\n" +
- " \"description\": {\n" +
- " \"text\": \"" + config.motd() + "\"\n" +
- " }\n" +
- "}");
+ 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(config.motd());
+
+ StatusServerResponse response = new StatusServerResponse();
+ response.setInfo(serverInfo);
channel.getCtx().writeAndFlush(response);
});
@@ -71,9 +68,7 @@ public class Main {
.doOnNext(channel -> log.info("{}", channel.getPacket()))
.subscribe(channel -> {
DisconnectPacket disconnectPacket = new DisconnectPacket();
- disconnectPacket.setReason("{\n" +
- " \"text\": \"Server is not available.\"\n" +
- "}");
+ disconnectPacket.setReason("Server is not available.");
channel.getCtx().writeAndFlush(disconnectPacket).channel().disconnect();
});
From ef984b28f0339b879222cf3bb005297f79e0c46b Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Wed, 28 Apr 2021 19:31:39 +0300
Subject: [PATCH 15/34] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?=
=?UTF-8?q?=D0=B5=D0=BD=20=D0=B7=D0=BD=D0=B0=D1=87=D0=BE=D0=BA=20=D1=81?=
=?UTF-8?q?=D0=B5=D1=80=D0=B2=D0=B5=D1=80=D0=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
libs.gradle | 3 ++-
.../packets/server/StatusServerResponse.java | 13 +++++++++---
server/build.gradle | 1 +
server/src/main/java/mc/server/Main.java | 20 ++++++++++++++++++
server/src/main/resources/config.yml | 4 ++--
server/src/main/resources/favicon.png | Bin 0 -> 1675 bytes
6 files changed, 35 insertions(+), 6 deletions(-)
create mode 100644 server/src/main/resources/favicon.png
diff --git a/libs.gradle b/libs.gradle
index fc2589b..a4eb76f 100644
--- a/libs.gradle
+++ b/libs.gradle
@@ -16,7 +16,8 @@ ext {
netty : 'io.netty:netty-all:4.1.22.Final',
reactor : 'io.projectreactor:reactor-core:3.4.5',
yaml : 'org.yaml:snakeyaml:1.28',
- json : 'com.eclipsesource.minimal-json:minimal-json:0.9.5'
+ json : 'com.eclipsesource.minimal-json:minimal-json:0.9.5',
+ ioutils : 'commons-io:commons-io:2.6'
]
libs.logger = [
diff --git a/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java b/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
index a238d20..32b26c7 100644
--- a/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
+++ b/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
@@ -48,6 +48,8 @@ import java.util.stream.Collector;
* "favicon": "data:image/png;base64,<data>"
* }
*
+ *
+ * `$.favicon` должен быть формата PNG и размеры 64x64 px
*/
@Data
public class StatusServerResponse implements ServerSidePacket {
@@ -59,11 +61,16 @@ public class StatusServerResponse implements ServerSidePacket {
@Override
public void writeSelf(NetByteBuf netByteBuf) {
- netByteBuf.writeString(Json.object()
+ JsonObject jsonObject = Json.object()
.add("version", createVersionObj())
.add("players", createPlayersObj())
- .add("description", Json.object().add("text", info.description()))
- .toString());
+ .add("description", Json.object().add("text", info.description()));
+
+ if (info.favicon() != null && !info.favicon().isEmpty()) {
+ jsonObject.add("favicon", info.favicon());
+ }
+
+ netByteBuf.writeString(jsonObject.toString());
}
private JsonObject createVersionObj() {
diff --git a/server/build.gradle b/server/build.gradle
index 46c8b98..3854cf5 100644
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -20,4 +20,5 @@ dependencies {
implementation libs.reactor
implementation libs.guava
implementation libs.yaml
+ implementation libs.ioutils
}
diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
index 0592fa1..c07e3c1 100644
--- a/server/src/main/java/mc/server/Main.java
+++ b/server/src/main/java/mc/server/Main.java
@@ -14,8 +14,13 @@ import mc.server.config.Config;
import mc.server.di.ConfigModule;
import mc.server.di.DaggerServerComponent;
import mc.server.di.ServerComponent;
+import org.apache.commons.io.IOUtils;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Base64;
import java.util.Collections;
@Slf4j
@@ -58,6 +63,10 @@ public class Main {
serverInfo.players().sample(Collections.emptyList());
serverInfo.description(config.motd());
+ if (config.iconPath() != null) {
+ serverInfo.favicon(faviconToBase64(config.iconPath()));
+ }
+
StatusServerResponse response = new StatusServerResponse();
response.setInfo(serverInfo);
@@ -75,4 +84,15 @@ public class Main {
server.bind(config.server().host(), config.server().port());
}
+
+ 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/resources/config.yml b/server/src/main/resources/config.yml
index af6b6aa..81df62d 100644
--- a/server/src/main/resources/config.yml
+++ b/server/src/main/resources/config.yml
@@ -9,5 +9,5 @@ players:
online: 0
icon:
- enable: false
- path: favicon.png
\ No newline at end of file
+ enable: true
+ path: src/main/resources/favicon.png
\ No newline at end of file
diff --git a/server/src/main/resources/favicon.png b/server/src/main/resources/favicon.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
From 30bb894b7ce2a426bdfe9fa93456255053d02187 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Wed, 28 Apr 2021 21:18:28 +0300
Subject: [PATCH 16/34] =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9=20=D0=BA?=
=?UTF-8?q?=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82:=20Text?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/mc/protocol/model/ServerInfo.java | 2 +
.../main/java/mc/protocol/model/lombok.config | 1 -
.../java/mc/protocol/model/text/Text.java | 46 +++++++++++++++++++
.../java/mc/protocol/model/text/TextTest.java | 30 ++++++++++++
4 files changed, 78 insertions(+), 1 deletion(-)
delete mode 100644 protocol/src/main/java/mc/protocol/model/lombok.config
create mode 100644 protocol/src/main/java/mc/protocol/model/text/Text.java
create mode 100644 protocol/src/test/java/mc/protocol/model/text/TextTest.java
diff --git a/protocol/src/main/java/mc/protocol/model/ServerInfo.java b/protocol/src/main/java/mc/protocol/model/ServerInfo.java
index 002d52b..6924d14 100644
--- a/protocol/src/main/java/mc/protocol/model/ServerInfo.java
+++ b/protocol/src/main/java/mc/protocol/model/ServerInfo.java
@@ -5,9 +5,11 @@ import lombok.Setter;
import lombok.ToString;
import lombok.RequiredArgsConstructor;
import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
import java.util.List;
+@Accessors(fluent = true)
@Getter
@Setter
@ToString
diff --git a/protocol/src/main/java/mc/protocol/model/lombok.config b/protocol/src/main/java/mc/protocol/model/lombok.config
deleted file mode 100644
index f4387a7..0000000
--- a/protocol/src/main/java/mc/protocol/model/lombok.config
+++ /dev/null
@@ -1 +0,0 @@
-lombok.accessors.fluent=true
\ No newline at end of file
diff --git a/protocol/src/main/java/mc/protocol/model/text/Text.java b/protocol/src/main/java/mc/protocol/model/text/Text.java
new file mode 100644
index 0000000..94607a2
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/model/text/Text.java
@@ -0,0 +1,46 @@
+package mc.protocol.model.text;
+
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@EqualsAndHashCode
+@ToString
+public class Text {
+
+ public static final Text EMPTY = of("");
+
+ private String content;
+
+ Text(String content) {
+ this.content = content;
+ }
+
+ public static Text of(String content) {
+ return new Text(content);
+ }
+
+ public static Text.Builder builder() {
+ return new Text.Builder();
+ }
+
+ public static class Builder {
+ private String content;
+
+ public Builder append(String content) {
+ if (this.content == null) {
+ this.content = content;
+ } else {
+ this.content += content;
+ }
+ return this;
+ }
+
+ public Text build() {
+ if (content == null) {
+ return EMPTY;
+ } else {
+ return new Text(content);
+ }
+ }
+ }
+}
diff --git a/protocol/src/test/java/mc/protocol/model/text/TextTest.java b/protocol/src/test/java/mc/protocol/model/text/TextTest.java
new file mode 100644
index 0000000..ed3d423
--- /dev/null
+++ b/protocol/src/test/java/mc/protocol/model/text/TextTest.java
@@ -0,0 +1,30 @@
+package mc.protocol.model.text;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class TextTest {
+
+ @Test
+ void emptyTest() {
+ Text actual = Text.builder().build();
+ Text expected = Text.EMPTY;
+
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ void contentTest() {
+ Text actual;
+ Text expected;
+
+ actual = Text.builder().append("123").build();
+ expected = new Text("123");
+ assertEquals(expected, actual);
+
+ actual = Text.builder().append("123").append("456").build();
+ expected = new Text("123456");
+ assertEquals(expected, actual);
+ }
+}
\ No newline at end of file
From df4c1b7c71528b105a824798d4cb68ba99f1ee37 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Wed, 28 Apr 2021 21:27:38 +0300
Subject: [PATCH 17/34] =?UTF-8?q?Text:=20=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB?=
=?UTF-8?q?=D0=BD=D0=B5=D0=BD=20children?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/mc/protocol/model/text/Text.java | 26 ++++++++++++++++---
.../java/mc/protocol/model/text/TextTest.java | 24 +++++++++++++++--
2 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/protocol/src/main/java/mc/protocol/model/text/Text.java b/protocol/src/main/java/mc/protocol/model/text/Text.java
index 94607a2..27041ec 100644
--- a/protocol/src/main/java/mc/protocol/model/text/Text.java
+++ b/protocol/src/main/java/mc/protocol/model/text/Text.java
@@ -1,5 +1,6 @@
package mc.protocol.model.text;
+import com.google.common.collect.ImmutableList;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@@ -10,13 +11,15 @@ public class Text {
public static final Text EMPTY = of("");
private String content;
+ private ImmutableList children;
- Text(String content) {
+ Text(String content, ImmutableList children) {
this.content = content;
+ this.children = children;
}
public static Text of(String content) {
- return new Text(content);
+ return new Text(content, null);
}
public static Text.Builder builder() {
@@ -25,6 +28,7 @@ public class Text {
public static class Builder {
private String content;
+ private ImmutableList.Builder childrenBuilder;
public Builder append(String content) {
if (this.content == null) {
@@ -35,11 +39,25 @@ public class Text {
return this;
}
+ public Builder append(Text text) {
+ if (text == null || EMPTY.equals(text)) {
+ return this;
+ }
+
+ if (this.childrenBuilder == null) {
+ this.childrenBuilder = ImmutableList.builder();
+ }
+
+ this.childrenBuilder.add(text);
+ return this;
+ }
+
public Text build() {
- if (content == null) {
+ if (content == null && childrenBuilder == null) {
return EMPTY;
} else {
- return new Text(content);
+ return new Text(content,
+ childrenBuilder == null ? null : childrenBuilder.build());
}
}
}
diff --git a/protocol/src/test/java/mc/protocol/model/text/TextTest.java b/protocol/src/test/java/mc/protocol/model/text/TextTest.java
index ed3d423..9513bef 100644
--- a/protocol/src/test/java/mc/protocol/model/text/TextTest.java
+++ b/protocol/src/test/java/mc/protocol/model/text/TextTest.java
@@ -1,5 +1,6 @@
package mc.protocol.model.text;
+import com.google.common.collect.ImmutableList;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -20,11 +21,30 @@ class TextTest {
Text expected;
actual = Text.builder().append("123").build();
- expected = new Text("123");
+ expected = new Text("123", null);
assertEquals(expected, actual);
actual = Text.builder().append("123").append("456").build();
- expected = new Text("123456");
+ expected = new Text("123456", null);
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ void childrenTest() {
+ Text actual;
+ Text expected;
+
+ actual = Text.builder().append("123").append((Text) null).build();
+ expected = new Text("123", null);
+ assertEquals(expected, actual);
+
+ actual = Text.builder().append("123").append(Text.EMPTY).build();
+ expected = new Text("123", null);
+ assertEquals(expected, actual);
+
+ Text child = Text.of("456");
+ actual = Text.builder().append("123").append(child).build();
+ expected = new Text("123", ImmutableList.of(child));
assertEquals(expected, actual);
}
}
\ No newline at end of file
From b255980c05f016107adf11ceee7bb5e875ac235f Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Wed, 28 Apr 2021 21:42:35 +0300
Subject: [PATCH 18/34] =?UTF-8?q?Text:=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD?=
=?UTF-8?q?=D1=91=D0=BD=20builder?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/mc/protocol/model/text/Text.java | 45 ++++++++++++-------
1 file changed, 29 insertions(+), 16 deletions(-)
diff --git a/protocol/src/main/java/mc/protocol/model/text/Text.java b/protocol/src/main/java/mc/protocol/model/text/Text.java
index 27041ec..cb4545b 100644
--- a/protocol/src/main/java/mc/protocol/model/text/Text.java
+++ b/protocol/src/main/java/mc/protocol/model/text/Text.java
@@ -4,6 +4,8 @@ import com.google.common.collect.ImmutableList;
import lombok.EqualsAndHashCode;
import lombok.ToString;
+import java.util.LinkedList;
+
@EqualsAndHashCode
@ToString
public class Text {
@@ -27,15 +29,10 @@ public class Text {
}
public static class Builder {
- private String content;
- private ImmutableList.Builder childrenBuilder;
+ private final LinkedList chain = new LinkedList<>();
public Builder append(String content) {
- if (this.content == null) {
- this.content = content;
- } else {
- this.content += content;
- }
+ chain.add(content);
return this;
}
@@ -44,21 +41,37 @@ public class Text {
return this;
}
- if (this.childrenBuilder == null) {
- this.childrenBuilder = ImmutableList.builder();
- }
-
- this.childrenBuilder.add(text);
+ chain.add(text);
return this;
}
public Text build() {
- if (content == null && childrenBuilder == null) {
+ if (chain.isEmpty()) {
return EMPTY;
- } else {
- return new Text(content,
- childrenBuilder == null ? null : childrenBuilder.build());
}
+
+ StringBuilder contentBuilder = null;
+ ImmutableList.Builder childrenBuilder = null;
+
+ for (Object element : chain) {
+ if (element instanceof String) {
+ if (contentBuilder == null) {
+ contentBuilder = new StringBuilder((String) element);
+ } else {
+ contentBuilder.append((String) element);
+ }
+ } else if (element instanceof Text) {
+ if (childrenBuilder == null) {
+ childrenBuilder = ImmutableList.builder();
+ }
+
+ childrenBuilder.add((Text) element);
+ }
+ }
+
+ return new Text(
+ contentBuilder == null ? null : contentBuilder.toString(),
+ childrenBuilder == null ? null : childrenBuilder.build());
}
}
}
From c722da2b0562afd3027c371825c7b5d38a60f453 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Wed, 28 Apr 2021 22:12:21 +0300
Subject: [PATCH 19/34] =?UTF-8?q?Text:=20=D1=83=D0=BF=D1=80=D0=BE=D1=89?=
=?UTF-8?q?=D0=B5=D0=BD=20builder?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/mc/protocol/model/text/Text.java | 56 +++++++++----------
.../mc/protocol/model/text/TextColor.java | 31 ++++++++++
.../mc/protocol/model/text/TextStyle.java | 38 +++++++++++++
.../java/mc/protocol/model/text/TextTest.java | 32 +++--------
4 files changed, 103 insertions(+), 54 deletions(-)
create mode 100644 protocol/src/main/java/mc/protocol/model/text/TextColor.java
create mode 100644 protocol/src/main/java/mc/protocol/model/text/TextStyle.java
diff --git a/protocol/src/main/java/mc/protocol/model/text/Text.java b/protocol/src/main/java/mc/protocol/model/text/Text.java
index cb4545b..0b5a8c3 100644
--- a/protocol/src/main/java/mc/protocol/model/text/Text.java
+++ b/protocol/src/main/java/mc/protocol/model/text/Text.java
@@ -1,10 +1,11 @@
package mc.protocol.model.text;
-import com.google.common.collect.ImmutableList;
import lombok.EqualsAndHashCode;
import lombok.ToString;
+import java.util.ArrayList;
import java.util.LinkedList;
+import java.util.List;
@EqualsAndHashCode
@ToString
@@ -12,16 +13,32 @@ public class Text {
public static final Text EMPTY = of("");
+ private TextColor color;
+ private TextStyle style;
private String content;
- private ImmutableList children;
+ private List children;
- Text(String content, ImmutableList children) {
+ Text(TextColor color, TextStyle style, String content, List children) {
+ this.color = color;
+ this.style = style;
this.content = content;
this.children = children;
}
public static Text of(String content) {
- return new Text(content, null);
+ return new Text(null, null, content, null);
+ }
+
+ public static Text of(TextColor color, String content) {
+ return new Text(color, null, content, null);
+ }
+
+ public static Text of(TextStyle style, String content) {
+ return new Text(null, style, content, null);
+ }
+
+ public static Text of(TextColor color, TextStyle style, String content) {
+ return new Text(color, style, content, null);
}
public static Text.Builder builder() {
@@ -29,12 +46,7 @@ public class Text {
}
public static class Builder {
- private final LinkedList chain = new LinkedList<>();
-
- public Builder append(String content) {
- chain.add(content);
- return this;
- }
+ private final LinkedList chain = new LinkedList<>();
public Builder append(Text text) {
if (text == null || EMPTY.equals(text)) {
@@ -50,28 +62,14 @@ public class Text {
return EMPTY;
}
- StringBuilder contentBuilder = null;
- ImmutableList.Builder childrenBuilder = null;
+ Text rootText = chain.pollFirst();
- for (Object element : chain) {
- if (element instanceof String) {
- if (contentBuilder == null) {
- contentBuilder = new StringBuilder((String) element);
- } else {
- contentBuilder.append((String) element);
- }
- } else if (element instanceof Text) {
- if (childrenBuilder == null) {
- childrenBuilder = ImmutableList.builder();
- }
-
- childrenBuilder.add((Text) element);
- }
+ if (!chain.isEmpty()) {
+ rootText.children = new ArrayList<>();
+ rootText.children.addAll(chain);
}
- return new Text(
- contentBuilder == null ? null : contentBuilder.toString(),
- childrenBuilder == null ? null : childrenBuilder.build());
+ return rootText;
}
}
}
diff --git a/protocol/src/main/java/mc/protocol/model/text/TextColor.java b/protocol/src/main/java/mc/protocol/model/text/TextColor.java
new file mode 100644
index 0000000..ba0b1c2
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/model/text/TextColor.java
@@ -0,0 +1,31 @@
+package mc.protocol.model.text;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+@Getter
+public enum TextColor {
+ //@formatter:off
+ BLACK ("black", '0'),
+ DARK_BLUE ("dark_blue", '1'),
+ DARK_GREEN ("dark_green", '2'),
+ DARK_AQUA ("dark_aqua", '3'),
+ DARK_RED ("dark_red", '4'),
+ DARK_PUEPLE("dark_purple", '5'),
+ GOLD ("gold", '6'),
+ GRAY ("gray", '7'),
+ DARK_GRAY ("dark_gray", '8'),
+ BLUE ("blue", '9'),
+ GREEN ("green", 'a'),
+ AQUA ("aqua", 'b'),
+ RED ("red", 'c'),
+ PUEPLE ("light_purple",'d'),
+ YELLOW ("yellow", 'e'),
+ WHITE ("white", 'f'),
+ RESET ("reset", 'r');
+ //@formatter:on
+
+ private final String name;
+ private final char code;
+}
diff --git a/protocol/src/main/java/mc/protocol/model/text/TextStyle.java b/protocol/src/main/java/mc/protocol/model/text/TextStyle.java
new file mode 100644
index 0000000..e4856e3
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/model/text/TextStyle.java
@@ -0,0 +1,38 @@
+package mc.protocol.model.text;
+
+import lombok.*;
+import lombok.experimental.Accessors;
+
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+@Builder(builderClassName = "Builder")
+@Accessors(fluent = true)
+@Getter
+@Setter(AccessLevel.PACKAGE)
+@EqualsAndHashCode
+@ToString
+@SuppressWarnings("java:S1845")
+public class TextStyle {
+
+ public static final TextStyle BOLD = new TextStyle(true, null, null, null, null);
+ public static final TextStyle ITALIC = new TextStyle(null, true, null, null, null);
+ public static final TextStyle UNDERLINE = new TextStyle(null, null, true, null, null);
+ public static final TextStyle STRIKETHOUGH = new TextStyle(null, null, null, true, null);
+ public static final TextStyle OBFUSCATED = new TextStyle(null, null, null, null, true);
+
+ public static final TextStyle RESET = new TextStyle(false, false, false, false, false);
+ public static final TextStyle NONE = new TextStyle(null, null, null, null, null);
+
+ private Boolean bold;
+ private Boolean italic;
+ private Boolean underline;
+ private Boolean strikethrough;
+ private Boolean obfuscated;
+
+ void merge(TextStyle style) {
+ if (style.bold != null) this.bold = style.bold;
+ if (style.italic != null) this.italic = style.italic;
+ if (style.underline != null) this.underline = style.underline;
+ if (style.strikethrough != null) this.strikethrough = style.strikethrough;
+ if (style.obfuscated != null) this.obfuscated = style.obfuscated;
+ }
+}
diff --git a/protocol/src/test/java/mc/protocol/model/text/TextTest.java b/protocol/src/test/java/mc/protocol/model/text/TextTest.java
index 9513bef..cbed53f 100644
--- a/protocol/src/test/java/mc/protocol/model/text/TextTest.java
+++ b/protocol/src/test/java/mc/protocol/model/text/TextTest.java
@@ -1,9 +1,10 @@
package mc.protocol.model.text;
-import com.google.common.collect.ImmutableList;
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.*;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
class TextTest {
@@ -20,31 +21,12 @@ class TextTest {
Text actual;
Text expected;
- actual = Text.builder().append("123").build();
- expected = new Text("123", null);
+ actual = Text.builder().append(Text.of("123")).build();
+ expected = new Text(null, null, "123", null);
assertEquals(expected, actual);
- actual = Text.builder().append("123").append("456").build();
- expected = new Text("123456", null);
- assertEquals(expected, actual);
- }
-
- @Test
- void childrenTest() {
- Text actual;
- Text expected;
-
- actual = Text.builder().append("123").append((Text) null).build();
- expected = new Text("123", null);
- assertEquals(expected, actual);
-
- actual = Text.builder().append("123").append(Text.EMPTY).build();
- expected = new Text("123", null);
- assertEquals(expected, actual);
-
- Text child = Text.of("456");
- actual = Text.builder().append("123").append(child).build();
- expected = new Text("123", ImmutableList.of(child));
+ actual = Text.builder().append(Text.of("123")).append(Text.of("456")).build();
+ expected = new Text(null, null, "123", List.of(Text.of("456")));
assertEquals(expected, actual);
}
}
\ No newline at end of file
From 54b9ccb7e5135dc2b28b02ec520273698b828c60 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Wed, 28 Apr 2021 22:29:47 +0300
Subject: [PATCH 20/34] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C?=
=?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20Text?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/mc/protocol/model/ServerInfo.java | 3 +-
.../java/mc/protocol/model/text/Text.java | 4 ++
.../packets/server/DisconnectPacket.java | 7 +--
.../packets/server/StatusServerResponse.java | 42 +--------------
.../serializer/ServerInfoSerializer.java | 51 +++++++++++++++++++
.../protocol/serializer/TextSerializer.java | 41 +++++++++++++++
server/src/main/java/mc/server/Main.java | 5 +-
7 files changed, 107 insertions(+), 46 deletions(-)
create mode 100644 protocol/src/main/java/mc/protocol/serializer/ServerInfoSerializer.java
create mode 100644 protocol/src/main/java/mc/protocol/serializer/TextSerializer.java
diff --git a/protocol/src/main/java/mc/protocol/model/ServerInfo.java b/protocol/src/main/java/mc/protocol/model/ServerInfo.java
index 6924d14..e5a7af7 100644
--- a/protocol/src/main/java/mc/protocol/model/ServerInfo.java
+++ b/protocol/src/main/java/mc/protocol/model/ServerInfo.java
@@ -6,6 +6,7 @@ import lombok.ToString;
import lombok.RequiredArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
+import mc.protocol.model.text.Text;
import java.util.List;
@@ -18,7 +19,7 @@ public class ServerInfo {
private final Version version = new Version();
private final Players players = new Players();
- private String description;
+ private Text description;
private String favicon;
@Getter
diff --git a/protocol/src/main/java/mc/protocol/model/text/Text.java b/protocol/src/main/java/mc/protocol/model/text/Text.java
index 0b5a8c3..11d1d50 100644
--- a/protocol/src/main/java/mc/protocol/model/text/Text.java
+++ b/protocol/src/main/java/mc/protocol/model/text/Text.java
@@ -1,12 +1,16 @@
package mc.protocol.model.text;
import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.ToString;
+import lombok.experimental.Accessors;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
+@Accessors(fluent = true)
+@Getter
@EqualsAndHashCode
@ToString
public class Text {
diff --git a/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java b/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
index c45891c..7eae3aa 100644
--- a/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
+++ b/protocol/src/main/java/mc/protocol/packets/server/DisconnectPacket.java
@@ -1,10 +1,11 @@
package mc.protocol.packets.server;
-import com.eclipsesource.json.Json;
import lombok.Data;
import mc.protocol.State;
import mc.protocol.io.NetByteBuf;
+import mc.protocol.model.text.Text;
import mc.protocol.packets.ServerSidePacket;
+import mc.protocol.serializer.TextSerializer;
/**
* Diconnect packet.
@@ -34,10 +35,10 @@ public class DisconnectPacket implements ServerSidePacket {
/**
* Причина отключения.
*/
- private String reason;
+ private Text reason;
@Override
public void writeSelf(NetByteBuf netByteBuf) {
- netByteBuf.writeString(Json.object().add("text", reason).toString());
+ netByteBuf.writeString(TextSerializer.toJsonObject(reason).toString());
}
}
diff --git a/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java b/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
index 32b26c7..35973c1 100644
--- a/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
+++ b/protocol/src/main/java/mc/protocol/packets/server/StatusServerResponse.java
@@ -1,15 +1,10 @@
package mc.protocol.packets.server;
-import com.eclipsesource.json.Json;
-import com.eclipsesource.json.JsonArray;
-import com.eclipsesource.json.JsonObject;
-import com.google.common.collect.Streams;
import lombok.Data;
import mc.protocol.io.NetByteBuf;
import mc.protocol.model.ServerInfo;
import mc.protocol.packets.ServerSidePacket;
-
-import java.util.stream.Collector;
+import mc.protocol.serializer.ServerInfoSerializer;
/**
* Status server packet, response.
@@ -61,39 +56,6 @@ public class StatusServerResponse implements ServerSidePacket {
@Override
public void writeSelf(NetByteBuf netByteBuf) {
- JsonObject jsonObject = Json.object()
- .add("version", createVersionObj())
- .add("players", createPlayersObj())
- .add("description", Json.object().add("text", info.description()));
-
- if (info.favicon() != null && !info.favicon().isEmpty()) {
- jsonObject.add("favicon", info.favicon());
- }
-
- netByteBuf.writeString(jsonObject.toString());
- }
-
- private JsonObject createVersionObj() {
- return Json.object()
- .add("name", info.version().name())
- .add("protocol", info.version().protocol());
- }
-
- private JsonObject createPlayersObj() {
- JsonArray sampleArr = info.players().sample().stream()
- .map(samplePlayer -> Json.object()
- .add("name", samplePlayer.name())
- .add("id", samplePlayer.id()))
- .collect(Collector.of(Json::array, JsonArray::add, StatusServerResponse::jsonArrayAddAll));
-
- return Json.object()
- .add("max", info.players().max())
- .add("online", info.players().online())
- .add("sample", sampleArr);
- }
-
- private static JsonArray jsonArrayAddAll(JsonArray jsonArrayTo, JsonArray jsonArrayFrom) {
- Streams.stream(jsonArrayFrom).forEach(jsonArrayTo::add);
- return jsonArrayTo;
+ netByteBuf.writeString(ServerInfoSerializer.toJsonObject(info).toString());
}
}
diff --git a/protocol/src/main/java/mc/protocol/serializer/ServerInfoSerializer.java b/protocol/src/main/java/mc/protocol/serializer/ServerInfoSerializer.java
new file mode 100644
index 0000000..3b98b3d
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/serializer/ServerInfoSerializer.java
@@ -0,0 +1,51 @@
+package mc.protocol.serializer;
+
+import com.eclipsesource.json.Json;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.Streams;
+import lombok.experimental.UtilityClass;
+import mc.protocol.model.ServerInfo;
+
+import java.util.stream.Collector;
+
+@UtilityClass
+public class ServerInfoSerializer {
+
+ public JsonObject toJsonObject(ServerInfo info) {
+ JsonObject jsonObject = Json.object()
+ .add("version", createVersionObj(info))
+ .add("players", createPlayersObj(info))
+ .add("description", TextSerializer.toJsonObject(info.description()));
+
+ if (info.favicon() != null && !info.favicon().isEmpty()) {
+ jsonObject.add("favicon", info.favicon());
+ }
+
+ return jsonObject;
+ }
+
+ private JsonObject createVersionObj(ServerInfo info) {
+ return Json.object()
+ .add("name", info.version().name())
+ .add("protocol", info.version().protocol());
+ }
+
+ private JsonObject createPlayersObj(ServerInfo info) {
+ JsonArray sampleArr = info.players().sample().stream()
+ .map(samplePlayer -> Json.object()
+ .add("name", samplePlayer.name())
+ .add("id", samplePlayer.id()))
+ .collect(Collector.of(Json::array, JsonArray::add, ServerInfoSerializer::jsonArrayAddAll));
+
+ return Json.object()
+ .add("max", info.players().max())
+ .add("online", info.players().online())
+ .add("sample", sampleArr);
+ }
+
+ private static JsonArray jsonArrayAddAll(JsonArray jsonArrayTo, JsonArray jsonArrayFrom) {
+ Streams.stream(jsonArrayFrom).forEach(jsonArrayTo::add);
+ return jsonArrayTo;
+ }
+}
diff --git a/protocol/src/main/java/mc/protocol/serializer/TextSerializer.java b/protocol/src/main/java/mc/protocol/serializer/TextSerializer.java
new file mode 100644
index 0000000..69f2ff3
--- /dev/null
+++ b/protocol/src/main/java/mc/protocol/serializer/TextSerializer.java
@@ -0,0 +1,41 @@
+package mc.protocol.serializer;
+
+import com.eclipsesource.json.Json;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import lombok.experimental.UtilityClass;
+import mc.protocol.model.text.Text;
+
+@UtilityClass
+public class TextSerializer {
+
+ public JsonObject toJsonObject(Text text) {
+ JsonObject jsonObject = Json.object();
+
+ if (text.content() != null) {
+ jsonObject.add("text", text.content());
+ }
+
+ if (text.color() != null) {
+ jsonObject.add("color", text.color().getName());
+ }
+
+ if (text.style() != null) {
+ //@formatter:off
+ if (text.style().bold() != null) jsonObject.add("bold", text.style().bold());
+ if (text.style().italic() != null) jsonObject.add("italic", text.style().italic());
+ if (text.style().underline() != null) jsonObject.add("underline", text.style().underline());
+ if (text.style().strikethrough() != null) jsonObject.add("strikethrough", text.style().strikethrough());
+ if (text.style().obfuscated() != null) jsonObject.add("obfuscated", text.style().obfuscated());
+ //@formatter:on
+ }
+
+ if (text.children() != null && !text.children().isEmpty()) {
+ JsonArray extra = Json.array();
+ text.children().forEach(child -> extra.add(toJsonObject(child)));
+ jsonObject.add("extra", extra);
+ }
+
+ return jsonObject;
+ }
+}
diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
index c07e3c1..5b38960 100644
--- a/server/src/main/java/mc/server/Main.java
+++ b/server/src/main/java/mc/server/Main.java
@@ -4,6 +4,7 @@ import lombok.extern.slf4j.Slf4j;
import mc.protocol.NettyServer;
import mc.protocol.ProtocolConstant;
import mc.protocol.model.ServerInfo;
+import mc.protocol.model.text.Text;
import mc.protocol.packets.PingPacket;
import mc.protocol.packets.client.HandshakePacket;
import mc.protocol.packets.client.LoginStartPacket;
@@ -61,7 +62,7 @@ public class Main {
serverInfo.players().max(config.players().maxOnlile());
serverInfo.players().online(config.players().onlile());
serverInfo.players().sample(Collections.emptyList());
- serverInfo.description(config.motd());
+ serverInfo.description(Text.of(config.motd()));
if (config.iconPath() != null) {
serverInfo.favicon(faviconToBase64(config.iconPath()));
@@ -77,7 +78,7 @@ public class Main {
.doOnNext(channel -> log.info("{}", channel.getPacket()))
.subscribe(channel -> {
DisconnectPacket disconnectPacket = new DisconnectPacket();
- disconnectPacket.setReason("Server is not available.");
+ disconnectPacket.setReason(Text.of("Server is not available."));
channel.getCtx().writeAndFlush(disconnectPacket).channel().disconnect();
});
From 626ad9c206662c03c977d469af156214273b4292 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Wed, 28 Apr 2021 22:31:16 +0300
Subject: [PATCH 21/34] lombok.config -> @lombok.Accessors
---
server/src/main/java/mc/server/config/Config.java | 2 ++
server/src/main/java/mc/server/config/lombok.config | 1 -
2 files changed, 2 insertions(+), 1 deletion(-)
delete mode 100644 server/src/main/java/mc/server/config/lombok.config
diff --git a/server/src/main/java/mc/server/config/Config.java b/server/src/main/java/mc/server/config/Config.java
index f8f5f14..310adf6 100644
--- a/server/src/main/java/mc/server/config/Config.java
+++ b/server/src/main/java/mc/server/config/Config.java
@@ -3,9 +3,11 @@ package mc.server.config;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
+import lombok.experimental.Accessors;
import java.nio.file.Path;
+@Accessors(fluent = true)
@Getter
@Setter
@ToString
diff --git a/server/src/main/java/mc/server/config/lombok.config b/server/src/main/java/mc/server/config/lombok.config
deleted file mode 100644
index f4387a7..0000000
--- a/server/src/main/java/mc/server/config/lombok.config
+++ /dev/null
@@ -1 +0,0 @@
-lombok.accessors.fluent=true
\ No newline at end of file
From e93a24d76510d1e4037c55e78da864dfc7299030 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Thu, 29 Apr 2021 15:40:17 +0300
Subject: [PATCH 22/34] use jOptSimple
---
libs.gradle | 3 +-
server/build.gradle | 1 +
server/src/main/java/mc/server/Main.java | 49 ++++++++++++++++++++----
3 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/libs.gradle b/libs.gradle
index a4eb76f..6bac138 100644
--- a/libs.gradle
+++ b/libs.gradle
@@ -17,7 +17,8 @@ ext {
reactor : 'io.projectreactor:reactor-core:3.4.5',
yaml : 'org.yaml:snakeyaml:1.28',
json : 'com.eclipsesource.minimal-json:minimal-json:0.9.5',
- ioutils : 'commons-io:commons-io:2.6'
+ ioutils : 'commons-io:commons-io:2.6',
+ jopt : 'net.sf.jopt-simple:jopt-simple:6.0-alpha-3'
]
libs.logger = [
diff --git a/server/build.gradle b/server/build.gradle
index 3854cf5..91cb14c 100644
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -21,4 +21,5 @@ dependencies {
implementation libs.guava
implementation libs.yaml
implementation libs.ioutils
+ implementation libs.jopt
}
diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
index 5b38960..a4bd7ab 100644
--- a/server/src/main/java/mc/server/Main.java
+++ b/server/src/main/java/mc/server/Main.java
@@ -1,5 +1,8 @@
package mc.server;
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.util.PathConverter;
import lombok.extern.slf4j.Slf4j;
import mc.protocol.NettyServer;
import mc.protocol.ProtocolConstant;
@@ -23,19 +26,15 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Collections;
+import java.util.List;
@Slf4j
public class Main {
- public static void main(String[] args) {
+ private void run(OptionSet optionSet) {
log.info("mc-project launch");
- ConfigModule configModule;
- if (args.length > 0) {
- configModule = new ConfigModule(Paths.get(args[0]));
- } else {
- configModule = new ConfigModule(Paths.get("config.yml"));
- }
+ ConfigModule configModule = new ConfigModule((Path) optionSet.valueOf("config"));
ServerComponent serverComponent = DaggerServerComponent.builder()
.configModule(configModule)
@@ -86,6 +85,42 @@ public class Main {
server.bind(config.server().host(), config.server().port());
}
+ @SuppressWarnings("java:S106")
+ public static void main(String[] args) {
+ OptionParser optionParser = createOptionParser();
+ OptionSet optionSet = optionParser.parse(args);
+
+ if (optionSet.has("help")) {
+ try {
+ optionParser.printHelpOn(System.out);
+ } catch (IOException e) {
+ System.err.printf("Can't print help page: %s%n", e.getMessage());
+ e.printStackTrace(System.err);
+ }
+ return;
+ }
+
+ if (log.isDebugEnabled()) {
+ optionSet.asMap().forEach((optionSpec, objects) -> {
+ if (optionSpec.isForHelp()) return;
+ log.debug("OptionSet | {} = {}", optionSpec.options(), objects);
+ });
+ }
+
+ new Main().run(optionSet);
+ }
+
+ private static OptionParser createOptionParser() {
+ OptionParser optionParser = new OptionParser();
+ optionParser.acceptsAll(List.of("h", "help"), "Help page").forHelp();
+ optionParser.accepts("config", "Path to configuration file")
+ .withRequiredArg()
+ .withValuesConvertedBy(new PathConverter())
+ .defaultsTo(Paths.get("config.yml"));
+
+ return optionParser;
+ }
+
private static String faviconToBase64(Path iconPath) {
try {
return "data:image/png;base64," +
From dc7b4a7ab0af9a37ea821f70c913e855e7e21f1c Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Thu, 29 Apr 2021 16:44:08 +0300
Subject: [PATCH 23/34] =?UTF-8?q?Text:=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD?=
=?UTF-8?q?=D0=B5=D0=BD=20=D0=B4=D0=B8=D0=B7=D0=B0=D0=B9=D0=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/mc/protocol/model/text/Text.java | 142 +++++++++++++-----
.../mc/protocol/model/text/TextStyle.java | 66 ++++++--
.../java/mc/protocol/model/text/TextTest.java | 12 +-
3 files changed, 158 insertions(+), 62 deletions(-)
diff --git a/protocol/src/main/java/mc/protocol/model/text/Text.java b/protocol/src/main/java/mc/protocol/model/text/Text.java
index 11d1d50..0472114 100644
--- a/protocol/src/main/java/mc/protocol/model/text/Text.java
+++ b/protocol/src/main/java/mc/protocol/model/text/Text.java
@@ -1,79 +1,139 @@
package mc.protocol.model.text;
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.ArrayList;
-import java.util.LinkedList;
import java.util.List;
@Accessors(fluent = true)
-@Getter
-@EqualsAndHashCode
-@ToString
+@AllArgsConstructor
+@Data
public class Text {
- public static final Text EMPTY = of("");
-
private TextColor color;
private TextStyle style;
private String content;
private List children;
- Text(TextColor color, TextStyle style, String content, List children) {
- this.color = color;
- this.style = style;
- this.content = content;
- this.children = children;
+ public static Text of(String string) {
+ return new Text(null, null, string, null);
}
- public static Text of(String content) {
- return new Text(null, null, content, null);
+ public static Text of(TextColor color, String string) {
+ return new Text(color, null, string, null);
}
- public static Text of(TextColor color, String content) {
- return new Text(color, null, content, null);
+ public static Text of(TextStyle style, String string) {
+ return new Text(null, style, string, null);
}
- public static Text of(TextStyle style, String content) {
- return new Text(null, style, content, null);
+ public static Text of(TextColor color, TextStyle style, String string) {
+ return new Text(color, style, string, null);
}
- public static Text of(TextColor color, TextStyle style, String content) {
- return new Text(color, style, content, null);
- }
-
- public static Text.Builder builder() {
- return new Text.Builder();
+ public static Builder builder() {
+ return new Builder();
}
+ @NoArgsConstructor
+ @ToString
public static class Builder {
- private final LinkedList chain = new LinkedList<>();
+
+ private StringBuilder contentBuilder;
+ private TextStyle.Builder styleBuilder;
+ private TextColor color;
+ private List children;
+
+ public Builder append(String content) {
+ if (this.contentBuilder == null) {
+ this.contentBuilder = new StringBuilder(content);
+ } else {
+ this.contentBuilder.append(content);
+ }
+ return this;
+ }
public Builder append(Text text) {
- if (text == null || EMPTY.equals(text)) {
- return this;
+ if (children == null) {
+ children = new ArrayList<>();
}
- chain.add(text);
+ children.add(text);
+ return this;
+ }
+
+ public Builder style(TextStyle style) {
+ //@formatter:off
+ if (style.bold() != null) bold(style.bold());
+ if (style.italic() != null) italic(style.italic());
+ if (style.underline() != null) underline(style.underline());
+ if (style.strikethrough() != null) strikethrough(style.strikethrough());
+ if (style.obfuscated() != null) obfuscated(style.obfuscated());
+ //@formatter:on
+
+ return this;
+ }
+
+ public Builder color(TextColor color) {
+ this.color = color;
+ return this;
+ }
+
+ public Builder bold(Boolean bold) {
+ if (this.styleBuilder == null) {
+ this.styleBuilder = TextStyle.builder();
+ }
+
+ this.styleBuilder.bold(bold);
+ return this;
+ }
+
+ public Builder italic(Boolean italic) {
+ if (this.styleBuilder == null) {
+ this.styleBuilder = TextStyle.builder();
+ }
+
+ this.styleBuilder.italic(italic);
+ return this;
+ }
+
+ public Builder underline(Boolean underline) {
+ if (this.styleBuilder == null) {
+ this.styleBuilder = TextStyle.builder();
+ }
+
+ this.styleBuilder.underline(underline);
+ return this;
+ }
+
+ public Builder strikethrough(Boolean strikethrough) {
+ if (this.styleBuilder == null) {
+ this.styleBuilder = TextStyle.builder();
+ }
+
+ this.styleBuilder.strikethrough(strikethrough);
+ return this;
+ }
+
+ public Builder obfuscated(Boolean obfuscated) {
+ if (this.styleBuilder == null) {
+ this.styleBuilder = TextStyle.builder();
+ }
+
+ this.styleBuilder.obfuscated(obfuscated);
return this;
}
public Text build() {
- if (chain.isEmpty()) {
- return EMPTY;
- }
-
- Text rootText = chain.pollFirst();
-
- if (!chain.isEmpty()) {
- rootText.children = new ArrayList<>();
- rootText.children.addAll(chain);
- }
-
- return rootText;
+ return new Text(
+ color,
+ styleBuilder == null ? null : styleBuilder.build(),
+ contentBuilder == null ? null : contentBuilder.toString(),
+ children);
}
}
}
diff --git a/protocol/src/main/java/mc/protocol/model/text/TextStyle.java b/protocol/src/main/java/mc/protocol/model/text/TextStyle.java
index e4856e3..06c6040 100644
--- a/protocol/src/main/java/mc/protocol/model/text/TextStyle.java
+++ b/protocol/src/main/java/mc/protocol/model/text/TextStyle.java
@@ -4,12 +4,8 @@ import lombok.*;
import lombok.experimental.Accessors;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
-@Builder(builderClassName = "Builder")
@Accessors(fluent = true)
-@Getter
-@Setter(AccessLevel.PACKAGE)
-@EqualsAndHashCode
-@ToString
+@Data
@SuppressWarnings("java:S1845")
public class TextStyle {
@@ -28,11 +24,59 @@ public class TextStyle {
private Boolean strikethrough;
private Boolean obfuscated;
- void merge(TextStyle style) {
- if (style.bold != null) this.bold = style.bold;
- if (style.italic != null) this.italic = style.italic;
- if (style.underline != null) this.underline = style.underline;
- if (style.strikethrough != null) this.strikethrough = style.strikethrough;
- if (style.obfuscated != null) this.obfuscated = style.obfuscated;
+ public static Builder builder() {
+ return new TextStyle.Builder();
+ }
+
+ @NoArgsConstructor
+ @ToString
+ public static class Builder {
+
+ private Boolean bold;
+ private Boolean italic;
+ private Boolean underline;
+ private Boolean strikethrough;
+ private Boolean obfuscated;
+
+ public Builder bold(Boolean bold) {
+ this.bold = bold;
+ return this;
+ }
+
+ public Builder italic(Boolean italic) {
+ this.italic = italic;
+ return this;
+ }
+
+ public Builder underline(Boolean underline) {
+ this.underline = underline;
+ return this;
+ }
+
+ public Builder strikethrough(Boolean strikethrough) {
+ this.strikethrough = strikethrough;
+ return this;
+ }
+
+ public Builder obfuscated(Boolean obfuscated) {
+ this.obfuscated = obfuscated;
+ return this;
+ }
+
+ public Builder merge(TextStyle style) {
+ //@formatter:off
+ if (style.bold != null) this.bold = style.bold;
+ if (style.italic != null) this.italic = style.italic;
+ if (style.underline != null) this.underline = style.underline;
+ if (style.strikethrough != null) this.strikethrough = style.strikethrough;
+ if (style.obfuscated != null) this.obfuscated = style.obfuscated;
+ //@formatter:on
+
+ return this;
+ }
+
+ public TextStyle build() {
+ return new TextStyle(bold, italic, underline, strikethrough, obfuscated);
+ }
}
}
diff --git a/protocol/src/test/java/mc/protocol/model/text/TextTest.java b/protocol/src/test/java/mc/protocol/model/text/TextTest.java
index cbed53f..601576c 100644
--- a/protocol/src/test/java/mc/protocol/model/text/TextTest.java
+++ b/protocol/src/test/java/mc/protocol/model/text/TextTest.java
@@ -8,24 +8,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
class TextTest {
- @Test
- void emptyTest() {
- Text actual = Text.builder().build();
- Text expected = Text.EMPTY;
-
- assertEquals(expected, actual);
- }
-
@Test
void contentTest() {
Text actual;
Text expected;
- actual = Text.builder().append(Text.of("123")).build();
+ actual = Text.builder().append("123").build();
expected = new Text(null, null, "123", null);
assertEquals(expected, actual);
- actual = Text.builder().append(Text.of("123")).append(Text.of("456")).build();
+ actual = Text.builder().append("123").append(Text.of("456")).build();
expected = new Text(null, null, "123", List.of(Text.of("456")));
assertEquals(expected, actual);
}
From ac0ebea708d89c84c4d5b91b06ffc2f45434bea8 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Thu, 29 Apr 2021 18:56:54 +0300
Subject: [PATCH 24/34] =?UTF-8?q?Text:=20=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5?=
=?UTF-8?q?=D1=80=D1=82=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B8=D0=B7=20legacy?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/mc/protocol/model/text/Text.java | 12 +++
.../mc/protocol/model/text/TextColor.java | 5 +-
.../protocol/serializer/TextSerializer.java | 88 +++++++++++++++++++
.../serializer/TextSerializerTest.java | 40 +++++++++
4 files changed, 142 insertions(+), 3 deletions(-)
create mode 100644 protocol/src/test/java/mc/protocol/serializer/TextSerializerTest.java
diff --git a/protocol/src/main/java/mc/protocol/model/text/Text.java b/protocol/src/main/java/mc/protocol/model/text/Text.java
index 0472114..d7527e2 100644
--- a/protocol/src/main/java/mc/protocol/model/text/Text.java
+++ b/protocol/src/main/java/mc/protocol/model/text/Text.java
@@ -4,8 +4,10 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
+import lombok.Getter;
import lombok.experimental.Accessors;
+import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -43,11 +45,21 @@ public class Text {
@ToString
public static class Builder {
+ @Getter(onMethod = @__(@Nullable))
private StringBuilder contentBuilder;
private TextStyle.Builder styleBuilder;
private TextColor color;
private List children;
+ public Builder append(char content) {
+ if (this.contentBuilder == null) {
+ this.contentBuilder = new StringBuilder();
+ }
+
+ this.contentBuilder.append(content);
+ return this;
+ }
+
public Builder append(String content) {
if (this.contentBuilder == null) {
this.contentBuilder = new StringBuilder(content);
diff --git a/protocol/src/main/java/mc/protocol/model/text/TextColor.java b/protocol/src/main/java/mc/protocol/model/text/TextColor.java
index ba0b1c2..8e914cc 100644
--- a/protocol/src/main/java/mc/protocol/model/text/TextColor.java
+++ b/protocol/src/main/java/mc/protocol/model/text/TextColor.java
@@ -20,10 +20,9 @@ public enum TextColor {
GREEN ("green", 'a'),
AQUA ("aqua", 'b'),
RED ("red", 'c'),
- PUEPLE ("light_purple",'d'),
+ PURPLE ("light_purple",'d'),
YELLOW ("yellow", 'e'),
- WHITE ("white", 'f'),
- RESET ("reset", 'r');
+ WHITE ("white", 'f');
//@formatter:on
private final String name;
diff --git a/protocol/src/main/java/mc/protocol/serializer/TextSerializer.java b/protocol/src/main/java/mc/protocol/serializer/TextSerializer.java
index 69f2ff3..8633d02 100644
--- a/protocol/src/main/java/mc/protocol/serializer/TextSerializer.java
+++ b/protocol/src/main/java/mc/protocol/serializer/TextSerializer.java
@@ -5,10 +5,17 @@ import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import lombok.experimental.UtilityClass;
import mc.protocol.model.text.Text;
+import mc.protocol.model.text.TextColor;
+import mc.protocol.model.text.TextStyle;
+
+import java.util.Map;
@UtilityClass
public class TextSerializer {
+ private static final Map legacyStyleCodes;
+ private static final Map legacyColorCodes;
+
public JsonObject toJsonObject(Text text) {
JsonObject jsonObject = Json.object();
@@ -38,4 +45,85 @@ public class TextSerializer {
return jsonObject;
}
+
+ /**
+ * Преобразование строки вида "&4красный" в {@link Text}.
+ *
+ * @param string тест
+ * @return Text
+ */
+ @SuppressWarnings({"java:S3776", "java:S2583", "java:S135"})
+ public Text fromPlain(String string) {
+ boolean flagSys = false;
+ Text.Builder rootTextBuilder = Text.builder();
+ Text.Builder textBuilder = rootTextBuilder;
+
+ for (char ch : string.toCharArray()) {
+ if (!flagSys) {
+ if ('&' == ch) {
+ flagSys = true;
+ } else {
+ textBuilder.append(ch);
+ }
+ continue;
+ }
+
+ if (!legacyStyleCodes.containsKey(ch) && !legacyColorCodes.containsKey(ch) && '&' == ch) {
+ textBuilder.append('&');
+ flagSys = false;
+ continue;
+ }
+
+ //noinspection ConstantConditions
+ if (textBuilder.contentBuilder() != null && textBuilder.contentBuilder().length() > 0) {
+ if (textBuilder != rootTextBuilder) {
+ rootTextBuilder.append(textBuilder.build());
+ }
+ textBuilder = Text.builder();
+ }
+
+ if (legacyStyleCodes.containsKey(ch)) {
+ textBuilder.style(legacyStyleCodes.get(ch));
+ } else {
+ textBuilder.color(legacyColorCodes.get(ch));
+ }
+
+ flagSys = false;
+ }
+
+ if (textBuilder != rootTextBuilder) {
+ rootTextBuilder.append(textBuilder.build());
+ }
+
+ return rootTextBuilder.build();
+ }
+
+ static {
+ legacyColorCodes = Map.ofEntries(
+ Map.entry('0', TextColor.BLACK),
+ Map.entry('1', TextColor.DARK_BLUE),
+ Map.entry('2', TextColor.DARK_GREEN),
+ Map.entry('3', TextColor.DARK_AQUA),
+ Map.entry('4', TextColor.DARK_RED),
+ Map.entry('5', TextColor.DARK_PUEPLE),
+ Map.entry('6', TextColor.GOLD),
+ Map.entry('7', TextColor.GRAY),
+ Map.entry('8', TextColor.DARK_GRAY),
+ Map.entry('9', TextColor.BLUE),
+ Map.entry('a', TextColor.GREEN),
+ Map.entry('b', TextColor.AQUA),
+ Map.entry('c', TextColor.RED),
+ Map.entry('d', TextColor.PURPLE),
+ Map.entry('e', TextColor.YELLOW),
+ Map.entry('f', TextColor.WHITE)
+ );
+
+ legacyStyleCodes = Map.of(
+ 'k', TextStyle.OBFUSCATED,
+ 'l', TextStyle.BOLD,
+ 'm', TextStyle.STRIKETHOUGH,
+ 'n', TextStyle.UNDERLINE,
+ 'o', TextStyle.ITALIC
+ );
+ }
}
diff --git a/protocol/src/test/java/mc/protocol/serializer/TextSerializerTest.java b/protocol/src/test/java/mc/protocol/serializer/TextSerializerTest.java
new file mode 100644
index 0000000..61bd4fa
--- /dev/null
+++ b/protocol/src/test/java/mc/protocol/serializer/TextSerializerTest.java
@@ -0,0 +1,40 @@
+package mc.protocol.serializer;
+
+import mc.protocol.model.text.Text;
+import mc.protocol.model.text.TextColor;
+import mc.protocol.model.text.TextStyle;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class TextSerializerTest {
+
+ @ParameterizedTest
+ @MethodSource("paramsPlain")
+ void fromPlain(String sample, Text expected) {
+ Text actual = TextSerializer.fromPlain(sample);
+ assertEquals(expected, actual);
+ }
+
+ @SuppressWarnings("unused")
+ static Stream paramsPlain() {
+ return Stream.of(
+ Arguments.of("text", Text.of("text")),
+ Arguments.of("&&text", Text.of("&text")),
+ Arguments.of("&ztext", Text.of("text")),
+ Arguments.of("&4red_text", Text.of(TextColor.DARK_RED, "red_text")),
+ Arguments.of("&l&4red_text", Text.of(TextColor.DARK_RED, TextStyle.BOLD, "red_text")),
+ Arguments.of("&4&lred_text", Text.of(TextColor.DARK_RED, TextStyle.BOLD, "red_text")),
+
+ Arguments.of("&4red_text &eyellow_text", Text.builder()
+ .color(TextColor.DARK_RED)
+ .append("red_text ")
+ .append(Text.of(TextColor.YELLOW, "yellow_text"))
+ .build())
+ );
+ }
+}
\ No newline at end of file
From aa0e9bce3bfc24a8f49f4530b6ac6362fb6cd797 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Thu, 29 Apr 2021 19:09:45 +0300
Subject: [PATCH 25/34] =?UTF-8?q?=D0=BC=D0=BD=D0=BE=D0=B3=D0=BE=D1=81?=
=?UTF-8?q?=D1=82=D1=80=D0=BE=D1=87=D0=BD=D1=8B=D0=B9=20motd?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
server/src/main/java/mc/server/Main.java | 3 ++-
server/src/main/resources/config.yml | 4 +++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
index a4bd7ab..b18143b 100644
--- a/server/src/main/java/mc/server/Main.java
+++ b/server/src/main/java/mc/server/Main.java
@@ -14,6 +14,7 @@ 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;
@@ -61,7 +62,7 @@ public class Main {
serverInfo.players().max(config.players().maxOnlile());
serverInfo.players().online(config.players().onlile());
serverInfo.players().sample(Collections.emptyList());
- serverInfo.description(Text.of(config.motd()));
+ serverInfo.description(TextSerializer.fromPlain(config.motd()));
if (config.iconPath() != null) {
serverInfo.favicon(faviconToBase64(config.iconPath()));
diff --git a/server/src/main/resources/config.yml b/server/src/main/resources/config.yml
index 81df62d..8ae56bf 100644
--- a/server/src/main/resources/config.yml
+++ b/server/src/main/resources/config.yml
@@ -2,7 +2,9 @@ server:
host: 127.0.0.1
port: 25565
-motd: 'mc-project::ZERO'
+motd: |
+ &bmc-project &8:: &4ZERO
+ &8develop by &7DmitriyMX
players:
max-online: 0
From 27c739ca09e7a7c078bfd8a87b31ac5980ef5aeb Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Thu, 29 Apr 2021 21:14:10 +0300
Subject: [PATCH 26/34] =?UTF-8?q?fix:=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0?=
=?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B8=20?=
=?UTF-8?q?=D0=B2=20NetByteBuf?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../main/java/mc/protocol/io/NetByteBuf.java | 15 +++++--------
.../mc/protocol/io/NetByteBufWriteTest.java | 22 +++++++++++--------
2 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/protocol/src/main/java/mc/protocol/io/NetByteBuf.java b/protocol/src/main/java/mc/protocol/io/NetByteBuf.java
index d1c3638..da59f07 100644
--- a/protocol/src/main/java/mc/protocol/io/NetByteBuf.java
+++ b/protocol/src/main/java/mc/protocol/io/NetByteBuf.java
@@ -93,19 +93,16 @@ public class NetByteBuf extends ByteBuf {
}
public void writeString(String string) {
- byte[] buf;
- int length = (int) string.codePoints().count();
+ byte[] buf = string.getBytes(StandardCharsets.UTF_8);
- if (length > Short.MAX_VALUE) {
- log.warn("String is too long: {} > {}", length, Short.MAX_VALUE);
- buf = string.substring(0, Short.MAX_VALUE).getBytes(StandardCharsets.UTF_8);
+ if (buf.length > Short.MAX_VALUE) {
+ log.warn("String is too long: {} > {}", buf.length, Short.MAX_VALUE);
writeVarInt(Short.MAX_VALUE);
+ writeBytes(buf, 0, Short.MAX_VALUE);
} else {
- buf = string.getBytes(StandardCharsets.UTF_8);
- writeVarInt(length);
+ writeVarInt(buf.length);
+ writeBytes(buf);
}
-
- writeBytes(buf);
}
//endregion
diff --git a/protocol/src/test/java/mc/protocol/io/NetByteBufWriteTest.java b/protocol/src/test/java/mc/protocol/io/NetByteBufWriteTest.java
index 74b6c5a..3386041 100644
--- a/protocol/src/test/java/mc/protocol/io/NetByteBufWriteTest.java
+++ b/protocol/src/test/java/mc/protocol/io/NetByteBufWriteTest.java
@@ -50,15 +50,15 @@ class NetByteBufWriteTest {
@ParameterizedTest
@MethodSource("paramsWriteString")
- void writeString(String string) {
+ void writeString(String string, int exceptedLength) {
ByteBuf byteBuf = Unpooled.buffer();
NetByteBuf netByteBuf = new NetByteBuf(byteBuf);
netByteBuf.writeString(string);
byte[] actualArray = netByteBuf.copy(0, netByteBuf.readableBytes()).array();
- int length = actualArray[0]; // допустим, что размер поместился в один байт
- assertEquals(string.codePoints().count(), length);
+ int actualLength = actualArray[0]; // допустим, что размер поместился в один байт
+ assertEquals(exceptedLength, actualLength);
byte[] dataBytes = new byte[actualArray.length - 1];
System.arraycopy(actualArray, 1, dataBytes, 0, dataBytes.length);
@@ -196,12 +196,16 @@ class NetByteBufWriteTest {
@SuppressWarnings("unused")
private static Stream paramsWriteString() {
return Stream.of(
- Arguments.of(""),
- Arguments.of("Latin"),
- Arguments.of("Кириллица"),
- Arguments.of("العربية"),
- Arguments.of("ﬦﬣﬡ"), // Алфавитные формы представления
- Arguments.of("\uD800\uDD07") // Эгейские цифры, [один]
+ Arguments.of("", 0),
+ Arguments.of("Latin", 5),
+ Arguments.of("Кириллица", 37),
+ // (9) -> "Кириллица"(18) => 18*2=36 (37?)
+ Arguments.of("العربية", 30),
+ // (7) -> "Ш§Щ„Ш№Ш±ШЁЩЉШ©"(14) => 14*2=28 (30?)
+ Arguments.of("ﬦﬣﬡ", 18), // Алфавитные формы представления
+ // (3) -> "ﬦﬣﬡ"(9) => 9*2=18
+ Arguments.of("\uD800\uDD07", 4) // Эгейские цифры, [один]
+ // (1) -> "𐄇" => ...4!
);
}
From 9b6fccd9bd741f34eac3c69e19d2aeb953c01254 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Thu, 29 Apr 2021 21:43:07 +0300
Subject: [PATCH 27/34] =?UTF-8?q?=D0=BF=D1=80=D0=B8=D1=87=D0=B8=D0=BD?=
=?UTF-8?q?=D0=B0=20=D0=BE=D1=82=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8?=
=?UTF-8?q?=D1=8F=20=D0=BE=D1=82=20=D1=81=D0=B5=D1=80=D0=B2=D0=B5=D1=80?=
=?UTF-8?q?=D0=B0=20=D0=B2=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3=D0=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
server/src/main/java/mc/server/Main.java | 3 +--
server/src/main/java/mc/server/config/Config.java | 1 +
server/src/main/java/mc/server/di/ConfigModule.java | 1 +
server/src/main/resources/config.yml | 2 ++
4 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
index b18143b..c839916 100644
--- a/server/src/main/java/mc/server/Main.java
+++ b/server/src/main/java/mc/server/Main.java
@@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j;
import mc.protocol.NettyServer;
import mc.protocol.ProtocolConstant;
import mc.protocol.model.ServerInfo;
-import mc.protocol.model.text.Text;
import mc.protocol.packets.PingPacket;
import mc.protocol.packets.client.HandshakePacket;
import mc.protocol.packets.client.LoginStartPacket;
@@ -78,7 +77,7 @@ public class Main {
.doOnNext(channel -> log.info("{}", channel.getPacket()))
.subscribe(channel -> {
DisconnectPacket disconnectPacket = new DisconnectPacket();
- disconnectPacket.setReason(Text.of("Server is not available."));
+ disconnectPacket.setReason(TextSerializer.fromPlain(config.disconnectReason()));
channel.getCtx().writeAndFlush(disconnectPacket).channel().disconnect();
});
diff --git a/server/src/main/java/mc/server/config/Config.java b/server/src/main/java/mc/server/config/Config.java
index 310adf6..07340fc 100644
--- a/server/src/main/java/mc/server/config/Config.java
+++ b/server/src/main/java/mc/server/config/Config.java
@@ -17,6 +17,7 @@ public class Config {
private final Players players = new Players();
private String motd;
+ private String disconnectReason;
private Path iconPath;
@Getter
diff --git a/server/src/main/java/mc/server/di/ConfigModule.java b/server/src/main/java/mc/server/di/ConfigModule.java
index 510b077..c4bd5b0 100644
--- a/server/src/main/java/mc/server/di/ConfigModule.java
+++ b/server/src/main/java/mc/server/di/ConfigModule.java
@@ -28,6 +28,7 @@ public class ConfigModule {
config.server().host(fromYamlPath("server/host", map, "127.0.0.1"));
config.server().port(fromYamlPath("server/port", map, 25565));
config.motd(fromYamlPath("motd", map, ""));
+ config.disconnectReason(fromYamlPath("disconnect-reason", map, ""));
config.players().maxOnlile(fromYamlPath("players/max-online", map, 0));
config.players().onlile(fromYamlPath("players/online", map, 0));
diff --git a/server/src/main/resources/config.yml b/server/src/main/resources/config.yml
index 8ae56bf..7bbd46a 100644
--- a/server/src/main/resources/config.yml
+++ b/server/src/main/resources/config.yml
@@ -6,6 +6,8 @@ motd: |
&bmc-project &8:: &4ZERO
&8develop by &7DmitriyMX
+disconnect-reason: '&4Server is not available.'
+
players:
max-online: 0
online: 0
From e72a8443cdbcafb1a3e090c67b59399280265940 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Thu, 29 Apr 2021 22:01:16 +0300
Subject: [PATCH 28/34] gradle upgrade
---
gradle/wrapper/gradle-wrapper.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 442d913..f371643 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
From d4f7192e92ff182e5b184bbb962c8f691624bb14 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Thu, 29 Apr 2021 23:23:21 +0300
Subject: [PATCH 29/34] =?UTF-8?q?gradle:=20=D0=BD=D0=B0=D0=B2=D0=BE=D0=B4?=
=?UTF-8?q?=D0=B8=D0=BC=20=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA=20?=
=?UTF-8?q?=D0=B2=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81?=
=?UTF-8?q?=D1=82=D1=8F=D1=85?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
libs.gradle | 5 +++--
logic.gradle | 1 +
protocol/build.gradle | 5 ++---
.../main/java/mc/protocol/di/ProtocolModule.java | 13 +++++--------
.../protocol/serializer/ServerInfoSerializer.java | 8 ++++++--
server/build.gradle | 13 ++++++++++---
6 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/libs.gradle b/libs.gradle
index 6bac138..691322b 100644
--- a/libs.gradle
+++ b/libs.gradle
@@ -6,14 +6,15 @@ def slf4j_version = '1.7.30'
def logback_version = '1.2.3'
def dagger2_version = '2.33'
def junit_version = '5.5.2'
+def netty_version = '4.1.22.Final'
ext {
libs = [
lombok : 'org.projectlombok:lombok:1.18.12',
annotations: 'com.google.code.findbugs:jsr305:3.0.2',
- guava : 'com.google.guava:guava:30.1-jre',
lang3 : 'org.apache.commons:commons-lang3:3.11',
- netty : 'io.netty:netty-all:4.1.22.Final',
+ netty : ["io.netty:netty-transport:${netty_version}",
+ "io.netty:netty-handler:${netty_version}"],
reactor : 'io.projectreactor:reactor-core:3.4.5',
yaml : 'org.yaml:snakeyaml:1.28',
json : 'com.eclipsesource.minimal-json:minimal-json:0.9.5',
diff --git a/logic.gradle b/logic.gradle
index eb5630f..68886aa 100644
--- a/logic.gradle
+++ b/logic.gradle
@@ -1,5 +1,6 @@
//file:noinspection GrUnresolvedAccess
apply plugin: 'java'
+apply plugin: 'java-library'
apply from: rootDir.toPath().resolve('libs.gradle').toFile()
String getProperty1(String propertyName1, String propertyName2) {
diff --git a/protocol/build.gradle b/protocol/build.gradle
index 1a4110a..03ac861 100644
--- a/protocol/build.gradle
+++ b/protocol/build.gradle
@@ -1,9 +1,8 @@
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
dependencies {
- implementation libs.netty
- implementation libs.reactor
- implementation libs.guava
+ api libs.netty
+ api libs.reactor
implementation libs.json
testImplementation libs.lang3
diff --git a/protocol/src/main/java/mc/protocol/di/ProtocolModule.java b/protocol/src/main/java/mc/protocol/di/ProtocolModule.java
index 479e6c9..167d27f 100644
--- a/protocol/src/main/java/mc/protocol/di/ProtocolModule.java
+++ b/protocol/src/main/java/mc/protocol/di/ProtocolModule.java
@@ -1,6 +1,5 @@
package mc.protocol.di;
-import com.google.common.collect.ImmutableMap;
import dagger.Module;
import dagger.Provides;
import io.netty.bootstrap.ServerBootstrap;
@@ -22,9 +21,11 @@ import mc.protocol.io.codec.ProtocolSplitter;
import mc.protocol.packets.Packet;
import reactor.core.publisher.Sinks;
+import javax.annotation.Nonnull;
import javax.inject.Provider;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
@Module
@@ -54,7 +55,7 @@ public class ProtocolModule {
return new ChannelInitializer<>() {
@Override
- protected void initChannel(SocketChannel socketChannel) {
+ protected void initChannel(@Nonnull SocketChannel socketChannel) {
ChannelPipeline pipeline = socketChannel.pipeline();
channelHandlerMapProvider.get().forEach(pipeline::addLast);
}
@@ -81,12 +82,8 @@ public class ProtocolModule {
@Provides
@ServerScope
Map, Sinks.Many> provideObservedMap() {
- ImmutableMap.Builder, Sinks.Many> builder = ImmutableMap.builder();
-
- Stream.of(State.values())
+ return Stream.of(State.values())
.flatMap(state -> state.getClientSidePackets().values().stream())
- .forEach(packetClass -> builder.put(packetClass, Sinks.many().multicast().directBestEffort()));
-
- return builder.build();
+ .collect(Collectors.toMap(packetClass -> packetClass, v -> Sinks.many().multicast().directBestEffort()));
}
}
diff --git a/protocol/src/main/java/mc/protocol/serializer/ServerInfoSerializer.java b/protocol/src/main/java/mc/protocol/serializer/ServerInfoSerializer.java
index 3b98b3d..f215b55 100644
--- a/protocol/src/main/java/mc/protocol/serializer/ServerInfoSerializer.java
+++ b/protocol/src/main/java/mc/protocol/serializer/ServerInfoSerializer.java
@@ -3,11 +3,13 @@ package mc.protocol.serializer;
import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
-import com.google.common.collect.Streams;
import lombok.experimental.UtilityClass;
import mc.protocol.model.ServerInfo;
+import java.util.Spliterator;
+import java.util.Spliterators;
import java.util.stream.Collector;
+import java.util.stream.StreamSupport;
@UtilityClass
public class ServerInfoSerializer {
@@ -45,7 +47,9 @@ public class ServerInfoSerializer {
}
private static JsonArray jsonArrayAddAll(JsonArray jsonArrayTo, JsonArray jsonArrayFrom) {
- Streams.stream(jsonArrayFrom).forEach(jsonArrayTo::add);
+ StreamSupport.stream(
+ Spliterators.spliteratorUnknownSize(jsonArrayFrom.iterator(), Spliterator.ORDERED), false)
+ .forEach(jsonArrayTo::add);
return jsonArrayTo;
}
}
diff --git a/server/build.gradle b/server/build.gradle
index 91cb14c..b4c92f4 100644
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -4,6 +4,10 @@
*/
//file:noinspection GrUnresolvedAccess
+plugins {
+ id 'com.github.johnrengelman.shadow' version '7.0.0'
+}
+
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
apply plugin: 'application'
@@ -16,10 +20,13 @@ dependencies {
implementation libs.logger.logback
- implementation libs.netty
- implementation libs.reactor
- implementation libs.guava
implementation libs.yaml
implementation libs.ioutils
implementation libs.jopt
}
+
+shadowJar {
+ archiveBaseName.set(jar.archiveBaseName.get())
+ archiveVersion.set(project.version as String)
+ archiveClassifier.set('')
+}
\ No newline at end of file
From 2b4e58ae160c2c5610e2fe5be538bf79bd0ba54f Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Fri, 30 Apr 2021 00:49:55 +0300
Subject: [PATCH 30/34] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.MD | 10 +++++++++-
server/build.gradle | 4 ++++
.../resources/{config.yml => config-sample.yml} | 5 +++--
server/src/main/resources/favicon.png | Bin 1675 -> 0 bytes
.../{logback.xml => logback-sample.xml} | 0
5 files changed, 16 insertions(+), 3 deletions(-)
rename server/src/main/resources/{config.yml => config-sample.yml} (72%)
delete mode 100644 server/src/main/resources/favicon.png
rename server/src/main/resources/{logback.xml => logback-sample.xml} (100%)
diff --git a/README.MD b/README.MD
index f0e5040..04e53ca 100644
--- a/README.MD
+++ b/README.MD
@@ -12,6 +12,14 @@
## Запуск
+### Gradle
+
```shell
-gradle :server:run
+gradle :server:run --args="--config=config.yml" --project-prop jvmArgs="-Dlogback.configurationFile=logback.xml"
+```
+
+### Jar
+
+```shell
+java -Dlogback.configurationFile=logback.xml -jar server.jar --config=config.yml
```
\ No newline at end of file
diff --git a/server/build.gradle b/server/build.gradle
index b4c92f4..4802380 100644
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -13,6 +13,10 @@ apply plugin: 'application'
application {
mainClassName = 'mc.server.Main'
+
+ if (project.hasProperty('jvmArgs')) {
+ applicationDefaultJvmArgs = List.of((project.jvmArgs as String).split('\\s+'))
+ }
}
dependencies {
diff --git a/server/src/main/resources/config.yml b/server/src/main/resources/config-sample.yml
similarity index 72%
rename from server/src/main/resources/config.yml
rename to server/src/main/resources/config-sample.yml
index 7bbd46a..c26428c 100644
--- a/server/src/main/resources/config.yml
+++ b/server/src/main/resources/config-sample.yml
@@ -12,6 +12,7 @@ players:
max-online: 0
online: 0
+# Размер значка: 64x64 px
icon:
- enable: true
- path: src/main/resources/favicon.png
\ No newline at end of file
+ enable: false
+ path: favicon.png
\ No newline at end of file
diff --git a/server/src/main/resources/favicon.png b/server/src/main/resources/favicon.png
deleted file mode 100644
index d512fc5472e1d4b4573ba22b5e3e71587dbd4c9f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
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
diff --git a/server/src/main/resources/logback.xml b/server/src/main/resources/logback-sample.xml
similarity index 100%
rename from server/src/main/resources/logback.xml
rename to server/src/main/resources/logback-sample.xml
From b90ab4b5dba258efdf7532917961fdde83587929 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Sat, 1 May 2021 00:21:18 +0300
Subject: [PATCH 31/34] =?UTF-8?q?cli:=20=D0=BF=D0=BE=D0=B4=D0=B3=D0=BE?=
=?UTF-8?q?=D1=82=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BE=D0=BA=D1=80=D1=83=D0=B6?=
=?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
server/src/main/java/mc/server/Main.java | 44 +++++++++++++++++++++---
1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
index c839916..6f57b77 100644
--- a/server/src/main/java/mc/server/Main.java
+++ b/server/src/main/java/mc/server/Main.java
@@ -21,20 +21,25 @@ import mc.server.di.ServerComponent;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
+import java.io.InputStream;
+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;
@Slf4j
+@SuppressWarnings("java:S106")
public class Main {
+ private static final String CLI_CONFIG = "config";
private void run(OptionSet optionSet) {
log.info("mc-project launch");
- ConfigModule configModule = new ConfigModule((Path) optionSet.valueOf("config"));
+ ConfigModule configModule = new ConfigModule((Path) optionSet.valueOf(CLI_CONFIG));
ServerComponent serverComponent = DaggerServerComponent.builder()
.configModule(configModule)
@@ -85,8 +90,7 @@ public class Main {
server.bind(config.server().host(), config.server().port());
}
- @SuppressWarnings("java:S106")
- public static void main(String[] args) {
+ public static void main(String[] args) throws IOException {
OptionParser optionParser = createOptionParser();
OptionSet optionSet = optionParser.parse(args);
@@ -98,6 +102,25 @@ public class Main {
e.printStackTrace(System.err);
}
return;
+ } else if (optionSet.has("init")) {
+ Path configPath = (Path) optionSet.valueOf(CLI_CONFIG);
+ Path logbackPath = Paths.get(System.getProperty("logback.configurationFile", "logback.xml"));
+
+ if (!initializeCheckFiles(configPath, logbackPath)) {
+ return;
+ }
+
+ InputStream configResource = Objects.requireNonNull(Main.class.getResourceAsStream("/config-sample.yml"));
+ InputStream logbackResource = Objects.requireNonNull(Main.class.getResourceAsStream("/logback-sample.xml"));
+
+ try(OutputStream configOut = Files.newOutputStream(configPath);
+ OutputStream logbackOut = Files.newOutputStream(logbackPath)) {
+ IOUtils.copy(configResource, configOut);
+ IOUtils.copy(logbackResource, logbackOut);
+ }
+
+ System.out.println("Initialization environment done.");
+ return;
}
if (log.isDebugEnabled()) {
@@ -113,10 +136,11 @@ public class Main {
private static OptionParser createOptionParser() {
OptionParser optionParser = new OptionParser();
optionParser.acceptsAll(List.of("h", "help"), "Help page").forHelp();
- optionParser.accepts("config", "Path to configuration file")
+ optionParser.accepts(CLI_CONFIG, "Path to configuration file")
.withRequiredArg()
.withValuesConvertedBy(new PathConverter())
.defaultsTo(Paths.get("config.yml"));
+ optionParser.accepts("init", "Initialize environment");
return optionParser;
}
@@ -131,4 +155,16 @@ public class Main {
return "";
}
}
+
+ private static boolean initializeCheckFiles(Path... paths) {
+ for (Path path : paths) {
+ if (Files.exists(path)) {
+ System.err.printf("File '%s' already exist. Initialization environment canceled.%n",
+ path.toAbsolutePath());
+ return false;
+ }
+ }
+
+ return true;
+ }
}
From b97bb8432d79fa53880dfc43e0bb45c509037c25 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Sat, 1 May 2021 15:34:00 +0300
Subject: [PATCH 32/34] =?UTF-8?q?cli:=20=D0=BF=D1=83=D1=82=D1=8C=20=D0=B4?=
=?UTF-8?q?=D0=BE=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BA=20?=
=?UTF-8?q?=D0=BB=D0=BE=D0=B3=D0=B3=D0=B5=D1=80=D0=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.MD | 4 +--
server/src/main/java/mc/server/Main.java | 34 ++++++++++++++++++++++--
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/README.MD b/README.MD
index 04e53ca..968e795 100644
--- a/README.MD
+++ b/README.MD
@@ -15,11 +15,11 @@
### Gradle
```shell
-gradle :server:run --args="--config=config.yml" --project-prop jvmArgs="-Dlogback.configurationFile=logback.xml"
+gradle :server:run --args="--config=config.yml --logconfig==logback.xml"
```
### Jar
```shell
-java -Dlogback.configurationFile=logback.xml -jar server.jar --config=config.yml
+java -jar server.jar --config=config.yml --logconfig==logback.xml
```
\ No newline at end of file
diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java
index 6f57b77..c5f506e 100644
--- a/server/src/main/java/mc/server/Main.java
+++ b/server/src/main/java/mc/server/Main.java
@@ -1,5 +1,8 @@
package mc.server;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.joran.spi.JoranException;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.util.PathConverter;
@@ -19,6 +22,7 @@ import mc.server.di.ConfigModule;
import mc.server.di.DaggerServerComponent;
import mc.server.di.ServerComponent;
import org.apache.commons.io.IOUtils;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
@@ -35,6 +39,7 @@ import java.util.Objects;
@SuppressWarnings("java:S106")
public class Main {
private static final String CLI_CONFIG = "config";
+ private static final String CLI_LOGCONFIG = "logconfig";
private void run(OptionSet optionSet) {
log.info("mc-project launch");
@@ -104,7 +109,7 @@ public class Main {
return;
} else if (optionSet.has("init")) {
Path configPath = (Path) optionSet.valueOf(CLI_CONFIG);
- Path logbackPath = Paths.get(System.getProperty("logback.configurationFile", "logback.xml"));
+ Path logbackPath = (Path) optionSet.valueOf(CLI_LOGCONFIG);
if (!initializeCheckFiles(configPath, logbackPath)) {
return;
@@ -123,6 +128,8 @@ public class Main {
return;
}
+ reconfigureLogback(optionSet);
+
if (log.isDebugEnabled()) {
optionSet.asMap().forEach((optionSpec, objects) -> {
if (optionSpec.isForHelp()) return;
@@ -135,12 +142,19 @@ public class Main {
private static OptionParser createOptionParser() {
OptionParser optionParser = new OptionParser();
+
optionParser.acceptsAll(List.of("h", "help"), "Help page").forHelp();
+ optionParser.accepts("init", "Initialize environment");
+
optionParser.accepts(CLI_CONFIG, "Path to configuration file")
.withRequiredArg()
.withValuesConvertedBy(new PathConverter())
.defaultsTo(Paths.get("config.yml"));
- optionParser.accepts("init", "Initialize environment");
+
+ optionParser.accepts(CLI_LOGCONFIG, "Path to logger configuratuin file")
+ .withRequiredArg()
+ .withValuesConvertedBy(new PathConverter())
+ .defaultsTo(Paths.get("logback.xml"));
return optionParser;
}
@@ -167,4 +181,20 @@ public class Main {
return true;
}
+
+ private static void reconfigureLogback(OptionSet optionSet) throws IOException {
+ LoggerContext logbackContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+ logbackContext.reset();
+ JoranConfigurator configurator = new JoranConfigurator();
+
+ Path logbackPath = (Path) optionSet.valueOf(CLI_LOGCONFIG);
+ try(InputStream in = Objects.requireNonNull(
+ Files.newInputStream(logbackPath), "File not found: " + logbackPath.toAbsolutePath())) {
+
+ configurator.setContext(logbackContext);
+ configurator.doConfigure(in);
+ } catch (JoranException e) {
+ throw new IOException(e);
+ }
+ }
}
From 80eab876b3a7bdc61b94374f70061efde90287a7 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Sat, 1 May 2021 15:37:11 +0300
Subject: [PATCH 33/34] =?UTF-8?q?cli:=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0?=
=?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=B4=D0=B5=D1=84=D0=BE=D0=BB?=
=?UTF-8?q?=D1=82=D0=BD=D1=8B=D0=B5=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE?=
=?UTF-8?q?=D0=B9=D0=BA=D0=B8=20logback?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
server/src/main/resources/logback-sample.xml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/server/src/main/resources/logback-sample.xml b/server/src/main/resources/logback-sample.xml
index 192c634..f72ea29 100644
--- a/server/src/main/resources/logback-sample.xml
+++ b/server/src/main/resources/logback-sample.xml
@@ -4,7 +4,7 @@
- %d{HH:mm:ss.SSS} %-5level [%35.35logger{34}] -- %msg%n
+ %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%35.35logger{34}] -- %msg%n
@@ -12,7 +12,9 @@
+
\ No newline at end of file
From 4d849efcf2070d80d33f1046953212b391ee74e0 Mon Sep 17 00:00:00 2001
From: DmitriyMX
Date: Sat, 1 May 2021 16:27:13 +0300
Subject: [PATCH 34/34] update README
---
README.MD | 96 +++++++++++++++++++++++++++++++++++++++++----
server/build.gradle | 5 ++-
2 files changed, 93 insertions(+), 8 deletions(-)
diff --git a/README.MD b/README.MD
index 968e795..352a11a 100644
--- a/README.MD
+++ b/README.MD
@@ -4,22 +4,104 @@


+Написанный с нуля сервер **Minecraft 1.12.2**.
+
+На данный момент может только показывать информацию о себе. Подключение к серверу не возможно.
+
---
+## Требования
+
* Java 11
----
-
## Запуск
-### Gradle
+Для запуска требуются некоторые файлы настроек. Для их генерации можно воспользоваться командой инициализации окружения:
```shell
-gradle :server:run --args="--config=config.yml --logconfig==logback.xml"
+java -jar server.jar --init
```
-### Jar
+После выполнить запуск самого сервера:
```shell
-java -jar server.jar --config=config.yml --logconfig==logback.xml
-```
\ No newline at end of file
+java -jar server.jar
+```
+
+### Параметры командной строки
+
+`--init`
+Инициализация окружения. Генерирует необхидимые для запуска сервера файлы.
+
+`--config=path/to/config.yml`
+Указание альтернативного пути для конфигурационного файла сервера.
+
+`--logconfig=path/to/logback.xml`
+Указание альтернативного пути для конфигурационного файла логгера (logback).
+
+## Настройки
+
+### Стилизованный текст
+
+Файл конфига позволяет использовать специальные коды для добавления цвета и стиля в текст.
+
+| Код | Цвет | Код | Стиль |
+| ---- | ------------------------------------------- | ---- | --------------------------------------------------------------- |
+| `&0` | Black | `&l` | Bold |
+| `&1` | Dark Blue | `&o` | Italic |
+| `&2` | Dark Green | `&n` | Underline |
+| `&3` | Dark Aqua | `&m` | Strikethrough |
+| `&4` | Dark Red | `&k` | Obfuscated |
+| `&5` | Dark Purple |
+| `&6` | Gold |
+| `&7` | Gray |
+| `&8` | Dark Gray |
+| `&9` | Blue |
+| `&a` | Green |
+| `&b` | Aqua |
+| `&c` | Red |
+| `&d` | Purple |
+| `&e` | Yellow |
+| `&f` | White |
+
+
+### motd
+
+```yaml
+motd: |
+ mc-project :: ZERO
+ develop by DmitriyMX
+```
+
+Настройка надписи, которая будет отображаться в списке серверов у клиента. Максимум может состоять из двух строк.
+
+### disconnect-reason
+
+```yaml
+disconnect-reason: Server is not available.
+```
+
+Причина отключения от сервера. Количество строк не ограничено.
+
+### players
+
+```yaml
+players:
+ max-online: 0
+ online: 0
+```
+
+Фиктивные данные об онлайне сервера.
+
+### icon
+
+```yaml
+icon:
+ enable: true
+ path: favicon.png
+```
+
+Использовать значок сервера.
+Настройка `enable` говорит о факте использования значка, а в настройке `path` указывается путь к значку.
+
+Формат значка должен быть **PNG** и быть размерами **64x64 px**. Другие форматы или размеры _не поддерживаются_.
\ No newline at end of file
diff --git a/server/build.gradle b/server/build.gradle
index 4802380..7b27ae3 100644
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -1,6 +1,9 @@
/*
Запуск
- gradle :server:run
+ gradle :server:run --args="--config=config.yml --logconfig==logback.xml"
+
+Сборка
+ gradle :server:shadowJar
*/
//file:noinspection GrUnresolvedAccess