Archived
0

Merge branch 'proto_1.12.2' into world

This commit is contained in:
2018-08-26 00:28:01 +03:00
19 changed files with 518 additions and 211 deletions

View File

@@ -0,0 +1,26 @@
package mc.core.network.proto_1_12_2;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
@RequiredArgsConstructor
public enum Direction {
BOTTOM(0), // -Y
TOP(1), // +Y
NORTH(2), // -Z
SOUTH(3), // +Z
WEST(4), // -X
EAST(5); // +X
public static Direction getById(final int id) {
return Arrays.stream(Direction.values())
.filter(direction -> direction.id == id)
.findFirst()
.orElse(null);
}
@Getter
private final int id;
}

View File

@@ -80,13 +80,18 @@ public enum State {
.put(0x0D, PlayerPositionPacket.class)
.put(0x0E, PlayerPositionAndLookPacket.class)
.put(0x0F, PlayerLookPacket.class)
.put(0x13, PlayerAbilitiesPacket.class)
.put(0x14, PlayerDiggingPacket.class)
.put(0x15, EntityActionPacket.class)
.put(0x1A, HeldItemChangePacket.class)
.put(0x1D, AnimationPacket.class)
.put(0x1F, PlayerBlockPlacementPacket.class)
.build(),
ImmutableMap.<Class<? extends SCPacket>, Integer>builder()
.put(BossBarPacket.class, 0x0C)
.put(ChatMessageServerPacket.class, 0x0F)
.put(PluginMessagePacket.class, 0x18)
.put(UnloadChunkPacket.class, 0x1D)
.put(ChangeGameState.class, 0x1E)
.put(KeepAlivePacket.class, 0x1F)
.put(ChunkDataPacket.class, 0x20)

View File

@@ -0,0 +1,45 @@
package mc.core.network.proto_1_12_2.packets;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import mc.core.network.CSPacket;
import mc.core.network.NetInputStream;
import java.util.Arrays;
@Getter
public class EntityActionPacket implements CSPacket {
@RequiredArgsConstructor
public enum Action {
START_SNEAKING(0),
STOP_SNEAKING(1),
LEAVE_BED(2), // Leave bed is only sent when the “Leave Bed” button is clicked on the sleep GUI, not when waking up due today time.
START_SPRINTING(3),
STOP_SPRINTING(4),
START_JUMP_WITH_HORSE(5),
STOP_JUMP_WITH_HORSE(6),
OPEN_HORSE_INVENTORY(7), // Open horse inventory is only sent when pressing the inventory key (default: E) while on a horse — all other methods of opening a horse's inventory (involving right-clicking or shift-right-clicking it) do not use this packet.
START_FLYING_WITH_ELYTRA(8);
public static Action getById(final int id) {
return Arrays.stream(Action.values())
.filter(action -> action.id == id)
.findFirst()
.orElse(null);
}
@Getter
private final int id;
}
private int entityId;
private Action action;
private int jumpBoost; // Only used by the “start jump with horse” action, in which case it ranges from 0 to 100. In all other cases it is 0.
@Override
public void readSelf(NetInputStream netStream) {
entityId = netStream.readVarInt();
action = Action.getById(netStream.readVarInt());
jumpBoost = netStream.readVarInt();
}
}

View File

@@ -4,22 +4,27 @@
*/
package mc.core.network.proto_1_12_2.packets;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import mc.core.network.CSPacket;
import mc.core.network.NetInputStream;
import mc.core.network.NetOutputStream;
import mc.core.network.SCPacket;
@NoArgsConstructor
@Getter
@Setter
@ToString
public class PlayerAbilitiesPacket implements SCPacket {
public class PlayerAbilitiesPacket implements SCPacket, CSPacket {
private boolean godMode = false;
private boolean flying = false;
private boolean canFly = false;
private boolean instantDestroyBlocks = false;
private float flyingSpeed = 0.05f;
private float fieldOfView = flyingSpeed;
private float walkingSpeed;
@Override
public void writeSelf(NetOutputStream netStream) {
@@ -33,4 +38,17 @@ public class PlayerAbilitiesPacket implements SCPacket {
netStream.writeFloat(flyingSpeed);
netStream.writeFloat(fieldOfView);
}
@Override
public void readSelf(NetInputStream netStream) {
byte flag = netStream.readByte();
//FIXME треубет проверки
godMode = (flag == 0x08);
canFly = (flag == 0x04);
flying = (flag == 0x02);
instantDestroyBlocks = (flag == 0x01);
flyingSpeed = netStream.readFloat();
walkingSpeed = netStream.readFloat();
}
}

View File

@@ -0,0 +1,31 @@
package mc.core.network.proto_1_12_2.packets;
import lombok.Getter;
import lombok.ToString;
import mc.core.Location;
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 Direction face;
/** true - main hand; false - off hand */
private boolean hand;
private float cursorX, cursorY, cursorZ;
@Override
public void readSelf(NetInputStream netStream) {
long compactedCoords = netStream.readLong();
double[] xyz = CompactedCoords.uncompressXYZ(compactedCoords);
location = new Location(xyz[0], xyz[1], xyz[2], null);
face = Direction.getById(netStream.readVarInt());
hand = (netStream.readVarInt() == 1);
cursorX = netStream.readFloat();
cursorY = netStream.readFloat();
cursorZ = netStream.readFloat();
}
}

View File

@@ -0,0 +1,56 @@
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.CSPacket;
import mc.core.network.NetInputStream;
import mc.core.network.proto_1_12_2.Direction;
import mc.core.utils.CompactedCoords;
import java.util.Arrays;
@Getter
@ToString
public class PlayerDiggingPacket implements CSPacket {
@RequiredArgsConstructor
public enum Status {
STARTED_DIGGING(0),
CANCELLED_DIGGING(1),
FINISHED_DIGGING(2),
DROP_ITEM_STACK(3),
DROP_ITEM(4),
/* Indicates that the currently held item should have its
* state updated such as eating food, pulling back bows,
* using buckets, etc. Location is always set to 0/0/0,
* Face is always set to -Y.
*/
SHOOT_ARROW(5),
FINISH_EATING(5),
SWAP_ITEM_IN_HAND(6);
public static Status getById(final int id) {
return Arrays.stream(Status.values())
.filter(status -> status.id == id)
.findFirst()
.orElse(null);
}
@Getter
private final int id;
}
private Status status;
private Location 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], null);
face = Direction.getById(netStream.readByte());
}
}

View File

@@ -0,0 +1,16 @@
package mc.core.network.proto_1_12_2.packets;
import lombok.Setter;
import mc.core.network.NetOutputStream;
import mc.core.network.SCPacket;
public class UnloadChunkPacket implements SCPacket {
@Setter
private int x, z;
@Override
public void writeSelf(NetOutputStream netStream) {
netStream.writeInt(x);
netStream.writeInt(z);
}
}

View File

@@ -1,138 +0,0 @@
package mc.core.network.proto_1_12_2.packets;
import mc.core.EntityLocation;
import mc.core.world.Biome;
import mc.core.world.World;
import mc.core.world.WorldType;
import mc.core.world.block.Block;
import mc.core.world.block.BlockFactory;
import mc.core.world.block.BlockType;
import mc.core.world.chunk.Chunk;
import mc.core.world.chunk.ChunkSection;
public class DummyWorld implements World {
private class DummyChunkSection implements ChunkSection {
@Override
public int getSkyLight(int x, int y, int z) {
if (y <= 3) return 0;
else return 15;
}
@Override
public void setSkyLight(int x, int y, int z, int lightLevel) {
}
@Override
public int getAddition(int x, int y, int z) {
return 0;
}
@Override
public void setAddition(int x, int y, int z, int value) {
}
@Override
public Biome getBiome(int localX, int localZ) {
return Biome.PLAINS;
}
@Override
public int getX() {
return 0;
}
@Override
public int getY() {
return 0;
}
@Override
public int getZ() {
return 0;
}
@Override
public void setBlock(Block block) {
}
@Override
public Block getBlock(int x, int y, int z) {
BlockFactory blockFactory = new BlockFactory();
if (y == 0) return blockFactory.create(BlockType.BEDROCK, x, y, z, getWorld());
else if (y >= 1 && y <= 2) return blockFactory.create(BlockType.DIRT, x, y, z, getWorld());
else if (y == 3) return blockFactory.create(BlockType.GRASS, x, y, z, getWorld());
else return blockFactory.create(BlockType.AIR, x, y, z, getWorld());
}
@Override
public World getWorld() {
return DummyWorld.this;
}
}
private class DummyChunk implements Chunk {
@Override
public World getWorld() {
return DummyWorld.this;
}
@Override
public void setWorld(World world) {
}
@Override
public ChunkSection getChunkSection(int height) {
if (height < 1) return new DummyChunkSection();
else return null;
}
@Override
public void setChunkSection(int height, ChunkSection chunkSection) {
}
@Override
public Biome getBiome(int localX, int localZ) {
return Biome.PLAINS;
}
@Override
public void setBiome(int localX, int localZ, Biome biome) {
}
@Override
public int getX() {
return 0;
}
@Override
public int getZ() {
return 0;
}
}
private final Chunk chunk = new DummyChunk();
@Override
public WorldType getWorldType() {
return WorldType.FLAT;
}
@Override
public EntityLocation getSpawn() {
return null;
}
@Override
public void setSpawn(EntityLocation location) {
}
@Override
public Chunk getChunk(int x, int z) {
return chunk;
}
@Override
public void setChunk(int x, int z, Chunk chunk) {
}
}

View File

@@ -2,15 +2,29 @@ package mc.core.network.proto_1_12_2.packets;
import com.google.common.io.ByteStreams;
import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream;
import mc.core.world.Biome;
import mc.core.world.World;
import org.junit.Assert;
import mc.core.world.WorldType;
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 java.io.*;
import java.io.IOException;
import java.io.InputStream;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class TestChunkdataPacket {
private static byte[] expectedPacketData;
private World world;
@BeforeClass
public static void beforeClassTest() throws IOException {
@@ -18,8 +32,48 @@ public class TestChunkdataPacket {
expectedPacketData = ByteStreams.toByteArray(inputStream);
}
private World createDummyWorld() {
return new DummyWorld();
@Before
public void prepareWorld() {
final ChunkSection chunkSection = mock(ChunkSection.class);
when(chunkSection.getSkyLight(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
int y = (int)invocation.getArguments()[1];
if (y <= 3) return 0;
else return 15;
});
when(chunkSection.getBiome(anyInt(), anyInt())).thenReturn(Biome.PLAINS);
when(chunkSection.getBlock(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
Object[] args = invocation.getArguments();
int x = (int) args[0];
int y = (int) args[1];
int z = (int) args[2];
BlockFactory blockFactory = new BlockFactory();
if (y == 0) return blockFactory.create(BlockType.BEDROCK, x, y, z, null);
else if (y >= 1 && y <= 2) return blockFactory.create(BlockType.DIRT, x, y, z, null);
else if (y == 3) return blockFactory.create(BlockType.GRASS, x, y, z, null);
else return blockFactory.create(BlockType.AIR, x, y, z, null);
});
world = mock(World.class);
when(world.getWorldType()).thenReturn(WorldType.FLAT);
when(world.getChunk(anyInt(), anyInt())).thenAnswer(invocation -> {
Object[] args = invocation.getArguments();
Chunk chunk = mock(Chunk.class);
when(chunk.getX()).thenReturn((int) args[0]);
when(chunk.getZ()).thenReturn((int) args[1]);
when(chunk.getBiome(anyInt(), anyInt())).thenReturn(Biome.PLAINS);
when(chunk.getChunkSection(anyInt())).thenAnswer(invocation1 -> {
int height = (int)invocation1.getArguments()[0];
if (height < 1) return chunkSection;
else return null;
});
return chunk;
});
}
@Test
@@ -27,14 +81,14 @@ public class TestChunkdataPacket {
ChunkDataPacket packet = new ChunkDataPacket();
packet.setX(0);
packet.setZ(0);
packet.setChunk(createDummyWorld().getChunk(0, 0));
packet.setChunk(world.getChunk(0, 0));
packet.setInitChunk(true);
ByteArrayOutputNetStream netStream = new ByteArrayOutputNetStream();
packet.writeSelf(netStream);
byte[] actualPacketData = netStream.toByteArray();
Assert.assertEquals(expectedPacketData.length, actualPacketData.length);
Assert.assertArrayEquals(expectedPacketData, actualPacketData);
assertEquals(expectedPacketData.length, actualPacketData.length);
assertArrayEquals(expectedPacketData, actualPacketData);
}
}