Archived
0

Merge branch 'proto_1.12.2' into world

This commit is contained in:
2018-10-08 12:23:52 +03:00
82 changed files with 1854 additions and 802 deletions

View File

@@ -1,4 +1,3 @@
group 'mc'
version '1.0-SNAPSHOT'
dependencies {
@@ -6,6 +5,5 @@ dependencies {
compile_excludeCopy project(':core')
/* Components */
compile (group: 'com.google.guava', name: 'guava', version: '24.1-jre')
compile (group: 'com.google.code.gson', name: 'gson', version: '2.8.2')
compile (group: 'com.google.code.gson', name: 'gson', version: '2.8.5')
}

View File

@@ -13,25 +13,31 @@ import java.util.UUID;
@Slf4j
public abstract class NetInputStream_p340 extends NetInputStream {
@Override
public int readVarInt() {
public int readVarInt(int[] countReadBytes) {
int numRead = 0;
int result = 0;
byte read;
do {
if ((numRead+1) > 5) {
log.warn("VarInt is too big");
break;
}
read = readByte();
int value = (read & 0b01111111);
result |= (value << (7 * numRead));
numRead++;
if (numRead > 5) {
log.warn("VarInt is too big");
break;
}
} while ((read & 0b10000000) != 0);
if (countReadBytes != null && countReadBytes.length == 1) countReadBytes[0] = numRead;
return result;
}
@Override
public int readVarInt() {
return readVarInt(null);
}
@Override
public String readString() {
int size = readVarInt();

View File

@@ -45,8 +45,7 @@ public class TeleportManager {
public void apply(int teleportId) {
if (teleportMap.containsKey(teleportId)) {
TpData data = teleportMap.remove(teleportId);
data.player.getLocation().setXYZ(data.newLocation);
data.player.getLocation().setYawPitch(data.newLocation);
data.player.getLocation().set(data.newLocation);
}
}

View File

@@ -4,7 +4,6 @@
*/
package mc.core.network.proto_1_12_2.packets;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@@ -17,7 +16,6 @@ import mc.core.world.chunk.Chunk;
import mc.core.world.chunk.ChunkSection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

View File

@@ -18,6 +18,11 @@ import mc.core.network.SCPacket;
@Setter
@ToString
public class PlayerAbilitiesPacket implements SCPacket, CSPacket {
private static final byte $GOD_MODE_MASK = 0x01,
$FLYING_MASK = 0x02,
$CAN_FLY_MASK = 0x04,
$IDB_MASK = 0x08;
private boolean godMode = false;
private boolean flying = false;
private boolean canFly = false;
@@ -29,10 +34,10 @@ public class PlayerAbilitiesPacket implements SCPacket, CSPacket {
@Override
public void writeSelf(NetOutputStream netStream) {
byte flag = 0;
if (godMode) flag = (byte)(flag | 0x01);
if (flying) flag = (byte)(flag | 0x02);
if (canFly) flag = (byte)(flag | 0x04);
if (instantDestroyBlocks) flag = (byte)(flag | 0x08);
if (godMode) flag = (byte)(flag | $GOD_MODE_MASK);
if (flying) flag = (byte)(flag | $FLYING_MASK);
if (canFly) flag = (byte)(flag | $CAN_FLY_MASK);
if (instantDestroyBlocks) flag = (byte)(flag | $IDB_MASK);
netStream.writeByte(flag);
netStream.writeFloat(flyingSpeed);
@@ -42,11 +47,10 @@ public class PlayerAbilitiesPacket implements SCPacket, CSPacket {
@Override
public void readSelf(NetInputStream netStream) {
byte flag = netStream.readByte();
//FIXME треубет проверки
godMode = (flag == 0x08);
canFly = (flag == 0x04);
flying = (flag == 0x02);
instantDestroyBlocks = (flag == 0x01);
godMode = (flag & $GOD_MODE_MASK) > 0;
canFly = (flag & $CAN_FLY_MASK) > 0;
flying = (flag & $FLYING_MASK) > 0;
instantDestroyBlocks = (flag & $IDB_MASK) > 0;
flyingSpeed = netStream.readFloat();
walkingSpeed = netStream.readFloat();

View File

@@ -2,16 +2,16 @@ package mc.core.network.proto_1_12_2.packets;
import lombok.Getter;
import lombok.ToString;
import mc.core.Location;
import mc.core.network.proto_1_12_2.serializers.BlockLocationSerializer;
import mc.core.world.block.BlockLocation;
import mc.core.network.CSPacket;
import mc.core.network.NetInputStream;
import mc.core.network.proto_1_12_2.Direction;
import mc.core.utils.CompactedCoords;
@Getter
@ToString
public class PlayerBlockPlacementPacket implements CSPacket {
private Location location;
private BlockLocation location;
private Direction face;
/** true - main hand; false - off hand */
private boolean hand;
@@ -20,8 +20,7 @@ public class PlayerBlockPlacementPacket implements CSPacket {
@Override
public void readSelf(NetInputStream netStream) {
long compactedCoords = netStream.readLong();
double[] xyz = CompactedCoords.uncompressXYZ(compactedCoords);
location = new Location(xyz[0], xyz[1], xyz[2]);
location = BlockLocationSerializer.fromLong(compactedCoords);
face = Direction.getById(netStream.readVarInt());
hand = (netStream.readVarInt() == 1);
cursorX = netStream.readFloat();

View File

@@ -3,11 +3,11 @@ package mc.core.network.proto_1_12_2.packets;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import mc.core.Location;
import mc.core.network.proto_1_12_2.serializers.BlockLocationSerializer;
import mc.core.world.block.BlockLocation;
import mc.core.network.CSPacket;
import mc.core.network.NetInputStream;
import mc.core.network.proto_1_12_2.Direction;
import mc.core.utils.CompactedCoords;
import java.util.Arrays;
@@ -42,15 +42,14 @@ public class PlayerDiggingPacket implements CSPacket {
}
private Status status;
private Location location;
private BlockLocation location;
private Direction face;
@Override
public void readSelf(NetInputStream netStream) {
status = Status.getById(netStream.readVarInt());
long compactCoord = netStream.readLong();
double[] xyz = CompactedCoords.uncompressXYZ(compactCoord);
location = new Location(xyz[0], xyz[1], xyz[2]);
location = BlockLocationSerializer.fromLong(compactCoord);
face = Direction.getById(netStream.readByte());
}
}

View File

@@ -48,8 +48,7 @@ public class PlayerPositionAndLookPacket implements SCPacket, CSPacket {
netStream.readDouble(),
netStream.readDouble(),
netStream.readFloat(),
netStream.readFloat(),
null
netStream.readFloat()
);
this.onGround = netStream.readBoolean();

View File

@@ -4,7 +4,7 @@
*/
package mc.core.network.proto_1_12_2.packets;
import mc.core.Location;
import mc.core.world.block.BlockLocation;
import mc.core.network.CSPacket;
import mc.core.network.NetInputStream;
@@ -12,7 +12,7 @@ public class TabCompletePacket implements CSPacket {
private String text;
private boolean assumeCommand;
private boolean hasPosition;
private Location location;
private BlockLocation location;
@Override
public void readSelf(NetInputStream netStream) {
@@ -27,7 +27,7 @@ public class TabCompletePacket implements CSPacket {
double y = (compactValue >> 26) & 0xFFF;
double z = compactValue << 38 >> 38; // is normal?
this.location = new Location(x, y, z);
this.location = new BlockLocation((int)x, (int)y, (int)z); //FIXME
}
}
}

View File

@@ -0,0 +1,63 @@
package mc.core.network.proto_1_12_2.serializers;
import mc.core.world.block.BlockLocation;
import static com.google.common.math.IntMath.isPowerOfTwo;
public class BlockLocationSerializer {
private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[] {0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
private static final int NUM_X_BITS = 1 + log2(smallestEncompassingPowerOfTwo(30000000));
private static final int NUM_Z_BITS = NUM_X_BITS;
private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS;
private static final int Y_SHIFT = NUM_Z_BITS;
private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS;
private static final long X_MASK = (1L << NUM_X_BITS) - 1L;
private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L;
private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L;
/*
* net.minecraft.util.math.MathHelper#log2(int)
*/
private static int log2(int value) {
return log2DeBruijn(value) - (isPowerOfTwo(value) ? 0 : 1);
}
/*
* net.minecraft.util.math.MathHelper#log2DeBruijn(int)
*/
private static int log2DeBruijn(int value) {
value = isPowerOfTwo(value) ? value : smallestEncompassingPowerOfTwo(value);
return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int)((long)value * 125613361L >> 27) & 31];
}
/*
* net.minecraft.util.math.MathHelper#smallestEncompassingPowerOfTwo(int)
*/
private static int smallestEncompassingPowerOfTwo(int value) {
int i = value - 1;
i = i | i >> 1;
i = i | i >> 2;
i = i | i >> 4;
i = i | i >> 8;
i = i | i >> 16;
return i + 1;
}
public static long toLong(BlockLocation location) {
return ((long)location.getX() & X_MASK) << X_SHIFT |
((long)location.getY() & Y_MASK) << Y_SHIFT |
((long)location.getZ() & Z_MASK);
}
public static BlockLocation fromLong(long value) {
BlockLocation location = BlockLocation.ZERO();
fromLong(value, location);
return location;
}
public static void fromLong(long value, BlockLocation location) {
location.setX((int)(value << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS));
location.setY((int)(value << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS));
location.setZ((int)(value << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS));
}
}

View File

@@ -0,0 +1,72 @@
package mc.core.network.proto_1_12_2.packets;
import mc.core.network.proto_1_12_2.NetInputStream_p340;
import java.io.ByteArrayInputStream;
public class ByteArrayInputNetStream extends NetInputStream_p340 {
private ByteArrayInputStream bais;
public ByteArrayInputNetStream(byte[] buff) {
bais = new ByteArrayInputStream(buff);
}
@Override
public boolean readBoolean() {
return false;
}
@Override
public byte readByte() {
return (byte) bais.read();
}
@Override
public void readBytes(byte[] buffer) {
}
@Override
public int readUnsignedByte() {
return 0;
}
@Override
public int readUnsignedShort() {
return 0;
}
@Override
public short readShort() {
return 0;
}
@Override
public int readInt() {
int ch1 = bais.read();
int ch2 = bais.read();
int ch3 = bais.read();
int ch4 = bais.read();
if ((ch1 | ch2 | ch3 | ch4) < 0) return 0;
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
@Override
public long readLong() {
return 0;
}
@Override
public float readFloat() {
return Float.intBitsToFloat(readInt());
}
@Override
public double readDouble() {
return 0;
}
@Override
public void skipBytes(int count) {
}
}

View File

@@ -0,0 +1,48 @@
package mc.core.network.proto_1_12_2.packets;
import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream;
import org.junit.jupiter.api.Test;
import java.util.Random;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ByteArrayInputNetStreamTest {
private Random rnd = new Random();
@Test
void readByte() {
final byte b0 = (byte) rnd.nextInt();
ByteArrayOutputNetStream netStream = new ByteArrayOutputNetStream();
netStream.writeByte(b0);
byte[] buffer = netStream.toByteArray();
ByteArrayInputNetStream netInputStream = new ByteArrayInputNetStream(buffer);
byte b1 = netInputStream.readByte();
assertEquals(b0, b1);
}
@Test
void readInt() {
final int i0 = rnd.nextInt();
ByteArrayOutputNetStream netStream = new ByteArrayOutputNetStream();
netStream.writeInt(i0);
byte[] buffer = netStream.toByteArray();
ByteArrayInputNetStream netInputStream = new ByteArrayInputNetStream(buffer);
int i1 = netInputStream.readInt();
assertEquals(i0, i1);
}
@Test
void readFloat() {
final float f0 = rnd.nextFloat();
ByteArrayOutputNetStream netStream = new ByteArrayOutputNetStream();
netStream.writeFloat(f0);
byte[] buffer = netStream.toByteArray();
ByteArrayInputNetStream netInputStream = new ByteArrayInputNetStream(buffer);
float f1 = netInputStream.readFloat();
assertEquals(f0, f1, 0.00001f);
}
}

View File

@@ -9,31 +9,31 @@ import mc.core.world.block.BlockFactory;
import mc.core.world.block.BlockType;
import mc.core.world.chunk.Chunk;
import mc.core.world.chunk.ChunkSection;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class TestChunkdataPacket {
class ChunkdataPacketTest {
private static byte[] expectedPacketData;
private World world;
@BeforeClass
public static void beforeClassTest() throws IOException {
InputStream inputStream = TestChunkdataPacket.class.getResourceAsStream("ChunkDataPacket.bin");
@BeforeAll
static void beforeClassTest() throws IOException {
InputStream inputStream = ChunkdataPacketTest.class.getResourceAsStream("ChunkDataPacket.bin");
expectedPacketData = ByteStreams.toByteArray(inputStream);
}
@Before
public void prepareWorld() {
@BeforeEach
void prepareWorld() {
final ChunkSection chunkSection = mock(ChunkSection.class);
when(chunkSection.getSkyLight(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
int y = (int)invocation.getArguments()[1];
@@ -77,7 +77,7 @@ public class TestChunkdataPacket {
}
@Test
public void test() {
void writePacket() {
ChunkDataPacket packet = new ChunkDataPacket();
packet.setX(0);
packet.setZ(0);

View File

@@ -0,0 +1,40 @@
package mc.core.network.proto_1_12_2.packets;
import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Random;
import static org.junit.jupiter.api.Assertions.assertEquals;
class PlayerAbilitiesPacketTest {
private Random rnd = new Random();
private PlayerAbilitiesPacket packet;
@BeforeEach
void before() {
packet = new PlayerAbilitiesPacket();
packet.setGodMode(rnd.nextBoolean());
packet.setFlying(rnd.nextBoolean());
packet.setCanFly(rnd.nextBoolean());
packet.setInstantDestroyBlocks(rnd.nextBoolean());
packet.setFlyingSpeed(rnd.nextFloat());
}
@Test
void writePacket() {
ByteArrayOutputNetStream netOutputStream = new ByteArrayOutputNetStream();
packet.writeSelf(netOutputStream);
ByteArrayInputNetStream netInputStream = new ByteArrayInputNetStream(netOutputStream.toByteArray());
PlayerAbilitiesPacket outPkt = new PlayerAbilitiesPacket();
outPkt.readSelf(netInputStream);
assertEquals(packet.isGodMode(), outPkt.isGodMode(), "god mode");
assertEquals(packet.isFlying(), outPkt.isFlying(), "flying");
assertEquals(packet.isCanFly(), outPkt.isCanFly(), "can fly");
assertEquals(packet.isInstantDestroyBlocks(), outPkt.isInstantDestroyBlocks(), "instant destroy block");
assertEquals(packet.getFlyingSpeed(), outPkt.getFlyingSpeed(), 0.00001f, "flying speed");
}
}

View File

@@ -0,0 +1,32 @@
package mc.core.network.proto_1_12_2.serializers;
import mc.core.world.block.BlockLocation;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.concurrent.ThreadLocalRandom;
import static org.junit.jupiter.api.Assertions.assertEquals;
class BlockLocationSerializerTest {
private static final ThreadLocalRandom rnd = ThreadLocalRandom.current();
private static final int minI = 0, maxI = 10;
private int x, y, z;
@BeforeEach
void before() {
x = rnd.nextInt(minI, maxI);
y = rnd.nextInt(minI, maxI);
z = rnd.nextInt(minI, maxI);
}
@Test
void serialize() {
BlockLocation location = new BlockLocation(x, y, z);
final long serializedCoords = BlockLocationSerializer.toLong(location);
BlockLocation deserLoc = BlockLocationSerializer.fromLong(serializedCoords);
assertEquals(location, deserLoc);
}
}