0

Merge branch 'feature/refactoring' into development

This commit is contained in:
2020-05-02 04:42:21 +03:00
15 changed files with 152 additions and 74 deletions

View File

@@ -1,10 +1,5 @@
apply plugin: 'java' apply plugin: 'java'
wrapper {
gradleVersion = '5.3'
distributionType = Wrapper.DistributionType.BIN
}
project.group = projectGroup project.group = projectGroup
project.version = projectVersion project.version = projectVersion

View File

@@ -0,0 +1,17 @@
package mc.protocol;
import mc.protocol.io.NetInputStream;
import mc.protocol.io.NetOutputStream;
public abstract class EmptyPacket implements Packet {
@Override
public void readSelf(NetInputStream netInputStream) {
// empty
}
@Override
public void writeSelf(NetOutputStream netOutputStream) {
// empty
}
}

View File

@@ -1,5 +1,8 @@
package mc.protocol; package mc.protocol;
import mc.protocol.io.NetInputStream;
import mc.protocol.io.NetOutputStream;
public interface Packet { public interface Packet {
void readSelf(NetInputStream netInputStream); void readSelf(NetInputStream netInputStream);

View File

@@ -2,10 +2,8 @@ package mc.protocol;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableBiMap;
import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.Setter;
import mc.protocol.handshake.client.HandshakePacket; import mc.protocol.handshake.client.HandshakePacket;
import mc.protocol.status.client.StatusServerRequest; import mc.protocol.status.client.StatusServerRequest;
import mc.protocol.status.server.StatusServerResponse; import mc.protocol.status.server.StatusServerResponse;
@@ -13,20 +11,23 @@ import mc.protocol.status.server.StatusServerResponse;
@RequiredArgsConstructor @RequiredArgsConstructor
public enum State { public enum State {
HANDSHAKING(-1){{ HANDSHAKING(-1,
setServerBoundPackets(ImmutableBiMap.of( // server bound
ImmutableBiMap.of(
0x00, HandshakePacket.class 0x00, HandshakePacket.class
)); )
}}, ),
PLAY(0), PLAY(0),
STATUS(1){{ STATUS(1,
setServerBoundPackets(ImmutableBiMap.of( // server bound
ImmutableBiMap.of(
0x00, StatusServerRequest.class 0x00, StatusServerRequest.class
)); ),
setClientBoundPackets(ImmutableBiMap.of( // client bound
ImmutableBiMap.of(
0x00, StatusServerResponse.class 0x00, StatusServerResponse.class
)); )
}}, ),
LOGIN(2); LOGIN(2);
public static State getById(int id) { public static State getById(int id) {
@@ -42,11 +43,20 @@ public enum State {
@Getter @Getter
private final int id; private final int id;
@Setter(value = AccessLevel.PROTECTED) private BiMap<Integer, Class<? extends Packet>> serverBoundPackets;
private BiMap<Integer, Class<? extends Packet>> clientBoundPackets; private BiMap<Integer, Class<? extends Packet>> clientBoundPackets;
@Setter(value = AccessLevel.PROTECTED) State(int id, BiMap<Integer, Class<? extends Packet>> serverBoundPackets) {
private BiMap<Integer, Class<? extends Packet>> serverBoundPackets; this.id = id;
this.serverBoundPackets = serverBoundPackets;
}
State(int id, BiMap<Integer, Class<? extends Packet>> serverBoundPackets, BiMap<Integer, Class<? extends Packet>> clientBoundPackets) {
this.id = id;
this.serverBoundPackets = serverBoundPackets;
this.clientBoundPackets = clientBoundPackets;
}
public Class<? extends Packet> getPacketById(PacketDirection direction, int id) { public Class<? extends Packet> getPacketById(PacketDirection direction, int id) {
if (direction == PacketDirection.CLIENT_BOUND) { if (direction == PacketDirection.CLIENT_BOUND) {

View File

@@ -1,11 +1,31 @@
package mc.protocol.handshake.client; package mc.protocol.handshake.client;
import lombok.Data; import lombok.Data;
import mc.protocol.NetInputStream;
import mc.protocol.NetOutputStream;
import mc.protocol.Packet; import mc.protocol.Packet;
import mc.protocol.State; import mc.protocol.State;
import mc.protocol.io.NetInputStream;
import mc.protocol.io.NetOutputStream;
/**
* Handshake packet.
*
* <p>Данный пакет заставляет сервер переключить текущий {@link State}</p>
*
* <p>Структура пакета
* <pre>
* | FIELD | TYPE | NOTES |
* |------------------|----------------|----------------------------------------------|
* | Protocol version | VarInt | Версия протокола [1] |
* | Server address | Stirng | Hostname или IP |
* | Server port | Unsigned Short | Порт сервера |
* | Next stage | VarInt | ID State на который необходимо переключиться |
*
* [1] - <a href="https://wiki.vg/Protocol_version_numbers" target="_top">Protocol version numbers</a>
* </pre></p>
*
* @see <a href="https://wiki.vg/index.php?title=Protocol&oldid=7368#Handshake" target="_top">Handshake</a>
* @see State
*/
@Data @Data
public class HandshakePacket implements Packet { public class HandshakePacket implements Packet {

View File

@@ -1,4 +1,4 @@
package mc.protocol; package mc.protocol.io;
public class DecoderException extends RuntimeException { public class DecoderException extends RuntimeException {

View File

@@ -1,4 +1,4 @@
package mc.protocol; package mc.protocol.io;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -101,6 +101,8 @@ public abstract class NetInputStream extends InputStream {
} }
public abstract byte readByte(); public abstract byte readByte();
public abstract int readBytes(byte[] buffer, int offset, int lengtn); public abstract int readBytes(byte[] buffer, int offset, int lengtn);
public abstract int readShort(); public abstract int readShort();
} }

View File

@@ -1,4 +1,4 @@
package mc.protocol; package mc.protocol.io;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
@@ -84,6 +84,8 @@ public abstract class NetOutputStream extends OutputStream {
} }
public abstract void writeByte(int value); public abstract void writeByte(int value);
public abstract void writeBytes(byte[] buffer, int offset, int lengtn); public abstract void writeBytes(byte[] buffer, int offset, int lengtn);
public abstract void writeShort(int value); public abstract void writeShort(int value);
} }

View File

@@ -1,6 +1,6 @@
package mc.protocol.coder; package mc.protocol.io.coder;
import mc.protocol.NetOutputStream; import mc.protocol.io.NetOutputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;

View File

@@ -1,22 +1,10 @@
package mc.protocol.coder; package mc.protocol.io.coder;
/*
Packet format:
| FIELD | TYPE | NOTES |
+------------+--------+-----------------------------------+
| SIZE | VarInt | = sizeOf(id) + sizeOf(byte_array) |
| PACKET ID | VarInt | |
| BYTE ARRAY | bytes | |
https://wiki.vg/index.php?title=Protocol&oldid=7368#Without_compression
*/
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import mc.protocol.NetInputStream;
import mc.protocol.Packet; import mc.protocol.Packet;
import mc.protocol.PacketDirection; import mc.protocol.PacketDirection;
import mc.protocol.State; import mc.protocol.State;
import mc.protocol.io.NetInputStream;
import java.util.Objects; import java.util.Objects;

View File

@@ -1,22 +1,13 @@
package mc.protocol.coder; package mc.protocol.io.coder;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import mc.protocol.*; import mc.protocol.Packet;
import mc.protocol.PacketDirection;
import mc.protocol.State;
import mc.protocol.io.NetOutputStream;
import java.util.Objects; import java.util.Objects;
/*
Packet format:
| FIELD | TYPE | NOTES |
+------------+--------+-----------------------------------+
| SIZE | VarInt | = sizeOf(id) + sizeOf(byte_array) |
| PACKET ID | VarInt | |
| BYTE ARRAY | bytes | |
https://wiki.vg/index.php?title=Protocol&oldid=7368#Without_compression
*/
@RequiredArgsConstructor @RequiredArgsConstructor
public class ProtocolEncoder { public class ProtocolEncoder {

View File

@@ -0,0 +1,13 @@
/*
Формат пакета без компрессии
| FIELD | TYPE | NOTES |
|-------------|--------|-----------------------------------|
| SIZE | VarInt | = sizeOf(id) + sizeOf(byte_array) |
| PACKET ID | VarInt | |
| PACKET DATA | bytes | |
https://wiki.vg/index.php?title=Protocol&oldid=7368#Without_compression
*/
package mc.protocol.io.coder;

View File

@@ -0,0 +1,29 @@
/*
Data types
| Type | Size (bytes) | Кодирование | Коментарий |
|----------------|-----------------------|-----------------------------------------------------|--------------------------------------------------------------------------|
| Boolean | 1 | True или False | True = 0x01; False = 0x00 |
| Byte | 1 | Число от -128 до 127 | 8-bit число со знаком |
| Unsigned Byte | 1 | Число от 0 до 255 | 8-bit без знаковое число |
| Short | 2 | Число от -32768 до 32767 | 16-bit число со знаком |
| Unsigned Short | 2 | Число от -32768 до 32767 | 16-bit без знаковое число |
| Int | 4 | Число от -2147483648 и 2147483647 | 32-bit число со знаком |
| Long | 8 | Число от -9223372036854775808 и 9223372036854775807 | 64-bit число со знаком |
| Float | 4 | 32-bit число одинарной точности (IEEE 754-2008) | [1] |
| Double | 8 | 64-bit число одинарной точности (IEEE 754-2008) | [2] |
| String (n) | >= 1 ; <= (n * 4) + 3 | Последовательность Unicode scalar values | В начале пишется длина строки в VarInt, после чего записываются символы. |
| | | | Каждый символ может состоять максимум из 4 байт. [3] |
| | | | Максимальная длина строки - 32767 (3 - это как раз размер VarInt для |
| | | | этого числа). |
| VarInt | >= 1 ; <= 5 | Число от -2147483648 и 2147483647 | 32-bit число с плавающей размерностью от 1 до 5 байт |
| VarLong | >= 1 ; <= 10 | Число от -9223372036854775808 и 9223372036854775807 | 64-bit число с плавающей размерностью от 1 до 10 байт |
[1] - https://en.wikipedia.org/wiki/Single-precision_floating-point_format
[2] - https://en.wikipedia.org/wiki/Double-precision_floating-point_format
[3] - http://unicode.org/glossary/#unicode_scalar_value
https://wiki.vg/index.php?title=Protocol&oldid=7368#Data_types
*/
package mc.protocol.io;

View File

@@ -1,18 +1,12 @@
package mc.protocol.status.client; package mc.protocol.status.client;
import mc.protocol.NetInputStream; import mc.protocol.EmptyPacket;
import mc.protocol.NetOutputStream;
import mc.protocol.Packet;
public class StatusServerRequest implements Packet { /**
* Status server packet, request.
*
* <p>Клиент запрашивает получение информации о сервере</p>
*/
public class StatusServerRequest extends EmptyPacket {
@Override
public void readSelf(NetInputStream netInputStream) {
// empty
}
@Override
public void writeSelf(NetOutputStream netOutputStream) {
// empty
}
} }

View File

@@ -1,10 +1,24 @@
package mc.protocol.status.server; package mc.protocol.status.server;
import lombok.Data; import lombok.Data;
import mc.protocol.NetInputStream;
import mc.protocol.NetOutputStream;
import mc.protocol.Packet; import mc.protocol.Packet;
import mc.protocol.io.NetInputStream;
import mc.protocol.io.NetOutputStream;
/**
* Status server packet, response.
*
* <p>Информация о сервере</p>
*
* <p>Структура пакета
* <pre>
* | FIELD | TYPE | NOTES |
* |---------------|--------|-----------------------------------------|
* | JSON Response | String | Информация о сервере в JSON формате [1] |
*
* [1] - <a href="https://wiki.vg/index.php?title=Server_List_Ping&oldid=7555#Response" target="_top">Server List Ping: Response</a>
* </pre></p>
*/
@Data @Data
public class StatusServerResponse implements Packet { public class StatusServerResponse implements Packet {