Merge branch 'proto_1.12.2' into world
This commit is contained in:
@@ -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')
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user