Minecraft 1.19

This commit is contained in:
LOOHP 2022-06-11 02:34:26 +08:00
parent 0f909c4c11
commit 8b37a26424
25 changed files with 211604 additions and 198129 deletions

16
pom.xml
View File

@ -24,7 +24,7 @@
<groupId>com.loohp</groupId> <groupId>com.loohp</groupId>
<artifactId>Limbo</artifactId> <artifactId>Limbo</artifactId>
<name>Limbo</name> <name>Limbo</name>
<version>0.6.15-ALPHA</version> <version>0.6.16-ALPHA</version>
<description>Standalone Limbo Minecraft Server.</description> <description>Standalone Limbo Minecraft Server.</description>
<url>https://github.com/LOOHP/Limbo</url> <url>https://github.com/LOOHP/Limbo</url>
@ -136,7 +136,7 @@
</executions> </executions>
</plugin> </plugin>
</plugins> </plugins>
<finalName>${project.artifactId}-${project.version}-1.18.2</finalName> <finalName>${project.artifactId}-${project.version}-1.19</finalName>
</build> </build>
<profiles> <profiles>
@ -231,7 +231,7 @@
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId> <artifactId>gson</artifactId>
<version>2.8.9</version> <version>2.8.5</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -256,31 +256,31 @@
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-gson</artifactId> <artifactId>adventure-text-serializer-gson</artifactId>
<version>4.9.3</version> <version>4.10.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-legacy</artifactId> <artifactId>adventure-text-serializer-legacy</artifactId>
<version>4.9.3</version> <version>4.10.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-plain</artifactId> <artifactId>adventure-text-serializer-plain</artifactId>
<version>4.9.3</version> <version>4.10.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId> <artifactId>adventure-api</artifactId>
<version>4.9.3</version> <version>4.10.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-nbt</artifactId> <artifactId>adventure-nbt</artifactId>
<version>4.9.3</version> <version>4.10.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -131,8 +131,8 @@ public class Limbo {
//=========================== //===========================
public final String SERVER_IMPLEMENTATION_VERSION = "1.18.2"; public final String SERVER_IMPLEMENTATION_VERSION = "1.19";
public final int SERVER_IMPLEMENTATION_PROTOCOL = 758; public final int SERVER_IMPLEMENTATION_PROTOCOL = 759;
public final String LIMBO_IMPLEMENTATION_VERSION; public final String LIMBO_IMPLEMENTATION_VERSION;
private AtomicBoolean isRunning; private AtomicBoolean isRunning;
@ -216,7 +216,7 @@ public class Limbo {
console.sendMessage("Loading packet id mappings from mapping.json ..."); console.sendMessage("Loading packet id mappings from mapping.json ...");
InputStreamReader reader = new InputStreamReader(new FileInputStream(mappingFile), StandardCharsets.UTF_8); InputStreamReader reader = new InputStreamReader(Files.newInputStream(mappingFile.toPath()), StandardCharsets.UTF_8);
JSONObject json = (JSONObject) new JSONParser().parse(reader); JSONObject json = (JSONObject) new JSONParser().parse(reader);
reader.close(); reader.close();

View File

@ -73,6 +73,7 @@ import com.loohp.limbo.network.protocol.packets.PacketStatusInPing;
import com.loohp.limbo.network.protocol.packets.PacketStatusInRequest; import com.loohp.limbo.network.protocol.packets.PacketStatusInRequest;
import com.loohp.limbo.network.protocol.packets.PacketStatusOutPong; import com.loohp.limbo.network.protocol.packets.PacketStatusOutPong;
import com.loohp.limbo.network.protocol.packets.PacketStatusOutResponse; import com.loohp.limbo.network.protocol.packets.PacketStatusOutResponse;
import com.loohp.limbo.network.protocol.packets.ServerboundChatCommandPacket;
import com.loohp.limbo.player.Player; import com.loohp.limbo.player.Player;
import com.loohp.limbo.player.PlayerInteractManager; import com.loohp.limbo.player.PlayerInteractManager;
import com.loohp.limbo.utils.BungeecordAdventureConversionUtils; import com.loohp.limbo.utils.BungeecordAdventureConversionUtils;
@ -201,6 +202,7 @@ public class ClientConnection extends Thread {
} }
public synchronized void sendPacket(PacketOut packet) throws IOException { public synchronized void sendPacket(PacketOut packet) throws IOException {
System.out.println(packet.getClass());
if (channel.writePacket(packet)) { if (channel.writePacket(packet)) {
setLastPacketTimestamp(System.currentTimeMillis()); setLastPacketTimestamp(System.currentTimeMillis());
} }
@ -626,11 +628,10 @@ public class ClientConnection extends Thread {
sendPacket(response); sendPacket(response);
} else if (packetIn instanceof PacketPlayInChat) { } else if (packetIn instanceof PacketPlayInChat) {
PacketPlayInChat chat = (PacketPlayInChat) packetIn; PacketPlayInChat chat = (PacketPlayInChat) packetIn;
if (chat.getMessage().startsWith("/")) { player.chat(chat.getMessage(), true, chat.getSignature(), chat.getTime());
Limbo.getInstance().dispatchCommand(player, chat.getMessage()); } else if (packetIn instanceof ServerboundChatCommandPacket) {
} else { ServerboundChatCommandPacket command = (ServerboundChatCommandPacket) packetIn;
player.chat(chat.getMessage(), true); Limbo.getInstance().dispatchCommand(player, "/" + command.getCommand());
}
} else if (packetIn instanceof PacketPlayInHeldItemChange) { } else if (packetIn instanceof PacketPlayInHeldItemChange) {
PacketPlayInHeldItemChange change = (PacketPlayInHeldItemChange) packetIn; PacketPlayInHeldItemChange change = (PacketPlayInHeldItemChange) packetIn;
PlayerSelectedSlotChangeEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerSelectedSlotChangeEvent(player, (byte) change.getSlot())); PlayerSelectedSlotChangeEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerSelectedSlotChangeEvent(player, (byte) change.getSlot()));

View File

@ -19,27 +19,25 @@
package com.loohp.limbo.network.protocol.packets; package com.loohp.limbo.network.protocol.packets;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import com.loohp.limbo.registry.Registry; import com.loohp.limbo.registry.Registry;
import com.loohp.limbo.utils.BitsUtils; import com.loohp.limbo.utils.BitsUtils;
import com.loohp.limbo.utils.DataTypeIO; import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.utils.NamespacedKey;
import com.loohp.limbo.world.Environment; import com.loohp.limbo.world.Environment;
import com.loohp.limbo.world.GeneratedBlockDataMappings; import com.loohp.limbo.world.GeneratedBlockDataMappings;
import net.querz.mca.Chunk; import net.querz.mca.Chunk;
import net.querz.mca.Section; import net.querz.mca.Section;
import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.ListTag; import net.querz.nbt.tag.ListTag;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.LinkedList;
import java.util.List;
public class ClientboundLevelChunkWithLightPacket extends PacketOut { public class ClientboundLevelChunkWithLightPacket extends PacketOut {
private int chunkX; private int chunkX;
@ -165,7 +163,7 @@ public class ClientboundLevelChunkWithLightPacket extends PacketOut {
int shift = 64 % newBits; int shift = 64 % newBits;
int longsNeeded = (int) Math.ceil(4096 / (double) (64 / newBits)); int longsNeeded = (int) Math.ceil(4096 / (double) (64 / newBits));
for (int u = 64; u <= bits.length(); u += 64) { for (int u = 64; u <= bits.length(); u += 64) {
bits = BitsUtils.shiftAfter(bits, u - shift, shift); BitsUtils.shiftAfter(bits, u - shift, shift);
} }
long[] formattedLongs = bits.toLongArray(); long[] formattedLongs = bits.toLongArray();
@ -182,7 +180,7 @@ public class ClientboundLevelChunkWithLightPacket extends PacketOut {
} }
} else { } else {
try { try {
dataOut.writeByte(15); dataOut.writeByte(16);
section.getBlockStates(); section.getBlockStates();
int longsNeeded = 1024; int longsNeeded = 1024;
List<Integer> list = new LinkedList<>(); List<Integer> list = new LinkedList<>();
@ -207,7 +205,7 @@ public class ClientboundLevelChunkWithLightPacket extends PacketOut {
u++; u++;
} }
int id = list.isEmpty() ? 0 : list.remove(0); int id = list.isEmpty() ? 0 : list.remove(0);
currentLong = currentLong << 15; currentLong = currentLong << 16;
currentLong |= id; currentLong |= id;
} }
DataTypeIO.writeVarInt(dataOut, longsNeeded); DataTypeIO.writeVarInt(dataOut, longsNeeded);

View File

@ -0,0 +1,99 @@
/*
* This file is part of Limbo.
*
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2022. Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.loohp.limbo.network.protocol.packets;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Optional;
import java.util.UUID;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.NetworkEncryptionUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
public class ClientboundPlayerChatPacket extends PacketOut {
private Component signedContent;
private Optional<Component> unsignedContent;
private int position;
private UUID sender;
private Instant time;
private NetworkEncryptionUtils.SignatureData saltSignature;
public ClientboundPlayerChatPacket(Component signedContent, Optional<Component> unsignedContent, int position, UUID sender, Instant time, NetworkEncryptionUtils.SignatureData saltSignature) {
this.signedContent = signedContent;
this.unsignedContent = unsignedContent;
this.position = position;
this.sender = sender;
this.time = time;
this.saltSignature = saltSignature;
}
public Component getSignedContent() {
return signedContent;
}
public Optional<Component> getUnsignedContent() {
return unsignedContent;
}
public int getPosition() {
return position;
}
public UUID getSender() {
return sender;
}
public Instant getTime() {
return time;
}
public NetworkEncryptionUtils.SignatureData getSaltSignature() {
return saltSignature;
}
@Override
public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeString(output, GsonComponentSerializer.gson().serialize(signedContent), StandardCharsets.UTF_8);
if (unsignedContent.isPresent()) {
output.writeBoolean(true);
DataTypeIO.writeString(output, GsonComponentSerializer.gson().serialize(unsignedContent.get()), StandardCharsets.UTF_8);
} else {
output.writeBoolean(false);
}
DataTypeIO.writeVarInt(output, position);
DataTypeIO.writeUUID(output, sender);
output.writeLong(time.toEpochMilli());
NetworkEncryptionUtils.SignatureData.write(output, saltSignature);
return buffer.toByteArray();
}
}

View File

@ -19,27 +19,23 @@
package com.loohp.limbo.network.protocol.packets; package com.loohp.limbo.network.protocol.packets;
import com.loohp.limbo.utils.DataTypeIO;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.UUID;
import com.loohp.limbo.utils.DataTypeIO; public class ClientboundSystemChatPacket extends PacketOut {
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
public class PacketPlayOutChat extends PacketOut {
private Component message; private Component message;
private int position; private int position;
private UUID sender;
public PacketPlayOutChat(Component message, int position, UUID sender) { public ClientboundSystemChatPacket(Component message, int position) {
this.message = message; this.message = message;
this.position = position; this.position = position;
this.sender = sender;
} }
public Component getMessage() { public Component getMessage() {
@ -50,10 +46,6 @@ public class PacketPlayOutChat extends PacketOut {
return position; return position;
} }
public UUID getSender() {
return sender;
}
@Override @Override
public byte[] serializePacket() throws IOException { public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@ -61,8 +53,7 @@ public class PacketPlayOutChat extends PacketOut {
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeString(output, GsonComponentSerializer.gson().serialize(message), StandardCharsets.UTF_8); DataTypeIO.writeString(output, GsonComponentSerializer.gson().serialize(message), StandardCharsets.UTF_8);
output.writeByte(position); DataTypeIO.writeVarInt(output, position);
DataTypeIO.writeUUID(output, sender);
return buffer.toByteArray(); return buffer.toByteArray();
} }

View File

@ -34,7 +34,15 @@ public class PacketLoginInLoginStart extends PacketIn {
} }
public PacketLoginInLoginStart(DataInputStream in) throws IOException { public PacketLoginInLoginStart(DataInputStream in) throws IOException {
this(DataTypeIO.readString(in, StandardCharsets.UTF_8)); this.username = DataTypeIO.readString(in, StandardCharsets.UTF_8);
boolean hasSigData = in.readBoolean();
if (hasSigData) {
in.readLong();
int publicKeyLength = DataTypeIO.readVarInt(in);
in.readFully(new byte[publicKeyLength]);
int signatureLength = DataTypeIO.readVarInt(in);
in.readFully(new byte[signatureLength]);
}
} }
public String getUsername() { public String getUsername() {

View File

@ -53,6 +53,7 @@ public class PacketLoginOutLoginSuccess extends PacketOut {
output.writeByte(Packet.getLoginOut().get(getClass())); output.writeByte(Packet.getLoginOut().get(getClass()));
DataTypeIO.writeUUID(output, uuid); DataTypeIO.writeUUID(output, uuid);
DataTypeIO.writeString(output, username, StandardCharsets.UTF_8); DataTypeIO.writeString(output, username, StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, 0);
return buffer.toByteArray(); return buffer.toByteArray();
} }

View File

@ -22,23 +22,44 @@ package com.loohp.limbo.network.protocol.packets;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Instant;
import com.loohp.limbo.utils.DataTypeIO; import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.NetworkEncryptionUtils;
import com.loohp.limbo.utils.NetworkEncryptionUtils.SignatureData;
public class PacketPlayInChat extends PacketIn { public class PacketPlayInChat extends PacketIn {
private String message; private String message;
private Instant time;
private NetworkEncryptionUtils.SignatureData signature;
private boolean previewed;
public PacketPlayInChat(String message) { public PacketPlayInChat(String message, Instant time, SignatureData signature, boolean previewed) {
this.message = message; this.message = message;
this.time = time;
this.signature = signature;
this.previewed = previewed;
} }
public PacketPlayInChat(DataInputStream in) throws IOException { public PacketPlayInChat(DataInputStream in) throws IOException {
this(DataTypeIO.readString(in, StandardCharsets.UTF_8)); this(DataTypeIO.readString(in, StandardCharsets.UTF_8), Instant.ofEpochMilli(in.readLong()), new NetworkEncryptionUtils.SignatureData(in), in.readBoolean());
} }
public String getMessage() { public String getMessage() {
return message; return message;
} }
public Instant getTime() {
return time;
}
public SignatureData getSignature() {
return signature;
}
public boolean isPreviewed() {
return previewed;
}
} }

View File

@ -19,20 +19,18 @@
package com.loohp.limbo.network.protocol.packets; package com.loohp.limbo.network.protocol.packets;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import com.loohp.limbo.utils.DataTypeIO; import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.GameMode;
import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.utils.NamespacedKey;
import com.loohp.limbo.world.Environment; import com.loohp.limbo.world.Environment;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.ListTag;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class PacketPlayOutLogin extends PacketOut { public class PacketPlayOutLogin extends PacketOut {
@ -145,15 +143,7 @@ public class PacketPlayOutLogin extends PacketOut {
DataTypeIO.writeString(output, new NamespacedKey(worlds.get(u).getName()).toString(), StandardCharsets.UTF_8); DataTypeIO.writeString(output, new NamespacedKey(worlds.get(u).getName()).toString(), StandardCharsets.UTF_8);
} }
DataTypeIO.writeCompoundTag(output, dimensionCodec); DataTypeIO.writeCompoundTag(output, dimensionCodec);
CompoundTag tag = null; DataTypeIO.writeString(output, world.getEnvironment().getNamespacedKey().toString(), StandardCharsets.UTF_8);
ListTag<CompoundTag> list = dimensionCodec.getCompoundTag("minecraft:dimension_type").getListTag("value").asCompoundTagList();
for (CompoundTag each : list) {
if (each.getString("name").equals(dimension.getNamespacedKey().toString())) {
tag = each.getCompoundTag("element");
break;
}
}
DataTypeIO.writeCompoundTag(output, tag != null ? tag : list.get(0).getCompoundTag("element"));
DataTypeIO.writeString(output, new NamespacedKey(world.getName()).toString(), StandardCharsets.UTF_8); DataTypeIO.writeString(output, new NamespacedKey(world.getName()).toString(), StandardCharsets.UTF_8);
output.writeLong(hashedSeed); output.writeLong(hashedSeed);
DataTypeIO.writeVarInt(output, maxPlayers); DataTypeIO.writeVarInt(output, maxPlayers);
@ -163,6 +153,7 @@ public class PacketPlayOutLogin extends PacketOut {
output.writeBoolean(enableRespawnScreen); output.writeBoolean(enableRespawnScreen);
output.writeBoolean(isDebug); output.writeBoolean(isDebug);
output.writeBoolean(isFlat); output.writeBoolean(isFlat);
output.writeBoolean(false);
return buffer.toByteArray(); return buffer.toByteArray();
} }

View File

@ -35,7 +35,7 @@ public class PacketPlayOutPlayerInfo extends PacketOut {
public enum PlayerInfoAction { public enum PlayerInfoAction {
ADD_PLAYER(0), UPDATE_GAMEMODE(1), UPDATE_LATENCY(2), UPDATE_DISPLAY_NAME(3), REMOVE_PLAYER(4); ADD_PLAYER(0), UPDATE_GAMEMODE(1), UPDATE_LATENCY(2), UPDATE_DISPLAY_NAME(3), REMOVE_PLAYER(4);
int id; private final int id;
PlayerInfoAction(int id) { PlayerInfoAction(int id) {
this.id = id; this.id = id;
@ -99,6 +99,7 @@ public class PacketPlayOutPlayerInfo extends PacketOut {
} else { } else {
output.writeBoolean(false); output.writeBoolean(false);
} }
output.writeBoolean(false);
break; break;
case REMOVE_PLAYER: case REMOVE_PLAYER:
break; break;

View File

@ -23,6 +23,7 @@ import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -37,7 +38,7 @@ public class PacketPlayOutPositionAndLook extends PacketOut {
Y_ROT((byte) 0x08), Y_ROT((byte) 0x08),
X_ROT((byte) 0x10); X_ROT((byte) 0x10);
byte bit; private final byte bit;
PlayerTeleportFlags(byte bit) { PlayerTeleportFlags(byte bit) {
this.bit = bit; this.bit = bit;
@ -64,7 +65,7 @@ public class PacketPlayOutPositionAndLook extends PacketOut {
this.yaw = yaw; this.yaw = yaw;
this.pitch = pitch; this.pitch = pitch;
this.teleportId = teleportId; this.teleportId = teleportId;
this.flags = Arrays.asList(flags).stream().collect(Collectors.toSet()); this.flags = new HashSet<>(Arrays.asList(flags));
this.dismountVehicle = dismountVehicle; this.dismountVehicle = dismountVehicle;
} }

View File

@ -37,12 +37,13 @@ public class PacketPlayOutSpawnEntity extends PacketOut {
private double z; private double z;
private float pitch; private float pitch;
private float yaw; private float yaw;
private float headYaw;
private int data; private int data;
private short velocityX; private short velocityX;
private short velocityY; private short velocityY;
private short velocityZ; private short velocityZ;
public PacketPlayOutSpawnEntity(int entityId, UUID uuid, EntityType type, double x, double y, double z, float pitch, float yaw, short velocityX, short velocityY, short velocityZ) { public PacketPlayOutSpawnEntity(int entityId, UUID uuid, EntityType type, double x, double y, double z, float pitch, float yaw, float headYaw, int data, short velocityX, short velocityY, short velocityZ) {
this.entityId = entityId; this.entityId = entityId;
this.uuid = uuid; this.uuid = uuid;
this.type = type; this.type = type;
@ -51,7 +52,8 @@ public class PacketPlayOutSpawnEntity extends PacketOut {
this.z = z; this.z = z;
this.pitch = pitch; this.pitch = pitch;
this.yaw = yaw; this.yaw = yaw;
this.data = 0; //TO-DO this.headYaw = headYaw;
this.data = data;
this.velocityX = velocityX; this.velocityX = velocityX;
this.velocityY = velocityY; this.velocityY = velocityY;
this.velocityZ = velocityZ; this.velocityZ = velocityZ;
@ -89,6 +91,10 @@ public class PacketPlayOutSpawnEntity extends PacketOut {
return yaw; return yaw;
} }
public float getHeadYaw() {
return headYaw;
}
public int getData() { public int getData() {
return data; return data;
} }
@ -119,10 +125,11 @@ public class PacketPlayOutSpawnEntity extends PacketOut {
output.writeDouble(z); output.writeDouble(z);
output.writeByte((byte) (int) (pitch * 256.0F / 360.0F)); output.writeByte((byte) (int) (pitch * 256.0F / 360.0F));
output.writeByte((byte) (int) (yaw * 256.0F / 360.0F)); output.writeByte((byte) (int) (yaw * 256.0F / 360.0F));
output.writeInt(data); output.writeByte((byte) (int) (headYaw * 256.0F / 360.0F));
output.writeShort((int) (velocityX * 8000)); DataTypeIO.writeVarInt(output, data);
output.writeShort((int) (velocityY * 8000)); output.writeShort(velocityX * 8000);
output.writeShort((int) (velocityZ * 8000)); output.writeShort(velocityY * 8000);
output.writeShort(velocityZ * 8000);
return buffer.toByteArray(); return buffer.toByteArray();
} }

View File

@ -1,130 +0,0 @@
/*
* This file is part of Limbo.
*
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2022. Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.loohp.limbo.network.protocol.packets;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.UUID;
import com.loohp.limbo.entity.EntityType;
import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayOutSpawnEntityLiving extends PacketOut {
private int entityId;
private UUID uuid;
private EntityType type;
private double x;
private double y;
private double z;
private float yaw;
private float pitch;
private float headPitch;
private short velocityX;
private short velocityY;
private short velocityZ;
public PacketPlayOutSpawnEntityLiving(int entityId, UUID uuid, EntityType type, double x, double y, double z, float yaw, float pitch, float headPitch, short velocityX, short velocityY, short velocityZ) {
this.entityId = entityId;
this.uuid = uuid;
this.type = type;
this.x = x;
this.y = y;
this.z = z;
this.yaw = yaw;
this.pitch = pitch;
this.headPitch = headPitch;
this.velocityX = velocityX;
this.velocityY = velocityY;
this.velocityZ = velocityZ;
}
public int getEntityId() {
return entityId;
}
public UUID getUuid() {
return uuid;
}
public EntityType getType() {
return type;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
public float getYaw() {
return yaw;
}
public float getPitch() {
return pitch;
}
public float getHeadPitch() {
return headPitch;
}
public short getVelocityX() {
return velocityX;
}
public short getVelocityY() {
return velocityY;
}
public short getVelocityZ() {
return velocityZ;
}
@Override
public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeVarInt(output, entityId);
DataTypeIO.writeUUID(output, uuid);
DataTypeIO.writeVarInt(output, type.getTypeId());
output.writeDouble(x);
output.writeDouble(y);
output.writeDouble(z);
output.writeByte((byte) (int) (yaw * 256.0F / 360.0F));
output.writeByte((byte) (int) (pitch * 256.0F / 360.0F));
output.writeByte((byte) (int) (headPitch * 256.0F / 360.0F));
output.writeShort((int) (velocityX * 8000));
output.writeShort((int) (velocityY * 8000));
output.writeShort((int) (velocityZ * 8000));
return buffer.toByteArray();
}
}

View File

@ -0,0 +1,79 @@
/*
* This file is part of Limbo.
*
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2022. Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.loohp.limbo.network.protocol.packets;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.NetworkEncryptionUtils.ArgumentSignatures;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
public class ServerboundChatCommandPacket extends PacketIn {
private String command;
private Instant time;
private ArgumentSignatures argumentSignatures;
private boolean commandPreview;
public ServerboundChatCommandPacket(String command, Instant time, ArgumentSignatures argumentSignatures, boolean commandPreview) {
this.command = command;
this.time = time;
this.argumentSignatures = argumentSignatures;
this.commandPreview = commandPreview;
}
public ServerboundChatCommandPacket(DataInputStream in) throws IOException {
this.command = DataTypeIO.readString(in, StandardCharsets.UTF_8);
this.time = Instant.ofEpochMilli(in.readLong());
long salt = in.readLong();
int size = DataTypeIO.readVarInt(in);
Map<String, byte[]> signatures = new HashMap<>(size);
for (int i = 0; i < size; i++) {
String key = DataTypeIO.readString(in, StandardCharsets.UTF_8);
int arraySize = DataTypeIO.readVarInt(in);
byte[] value = new byte[arraySize];
in.readFully(value);
signatures.put(key, value);
}
this.argumentSignatures = new ArgumentSignatures(salt, signatures);
this.commandPreview = in.readBoolean();
}
public String getCommand() {
return command;
}
public Instant getTime() {
return time;
}
public ArgumentSignatures getArgumentSignatures() {
return argumentSignatures;
}
public boolean isCommandPreview() {
return commandPreview;
}
}

View File

@ -19,10 +19,6 @@
package com.loohp.limbo.player; package com.loohp.limbo.player;
import java.io.IOException;
import java.time.Duration;
import java.util.UUID;
import com.loohp.limbo.Limbo; import com.loohp.limbo.Limbo;
import com.loohp.limbo.commands.CommandSender; import com.loohp.limbo.commands.CommandSender;
import com.loohp.limbo.entity.DataWatcher; import com.loohp.limbo.entity.DataWatcher;
@ -38,7 +34,8 @@ import com.loohp.limbo.network.protocol.packets.ClientboundClearTitlesPacket;
import com.loohp.limbo.network.protocol.packets.ClientboundSetSubtitleTextPacket; import com.loohp.limbo.network.protocol.packets.ClientboundSetSubtitleTextPacket;
import com.loohp.limbo.network.protocol.packets.ClientboundSetTitleTextPacket; import com.loohp.limbo.network.protocol.packets.ClientboundSetTitleTextPacket;
import com.loohp.limbo.network.protocol.packets.ClientboundSetTitlesAnimationPacket; import com.loohp.limbo.network.protocol.packets.ClientboundSetTitlesAnimationPacket;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutChat; import com.loohp.limbo.network.protocol.packets.ClientboundSystemChatPacket;
import com.loohp.limbo.network.protocol.packets.PacketOut;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutGameState; import com.loohp.limbo.network.protocol.packets.PacketPlayOutGameState;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutHeldItemChange; import com.loohp.limbo.network.protocol.packets.PacketPlayOutHeldItemChange;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerListHeaderFooter; import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerListHeaderFooter;
@ -47,8 +44,8 @@ import com.loohp.limbo.network.protocol.packets.PacketPlayOutResourcePackSend;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutRespawn; import com.loohp.limbo.network.protocol.packets.PacketPlayOutRespawn;
import com.loohp.limbo.utils.BungeecordAdventureConversionUtils; import com.loohp.limbo.utils.BungeecordAdventureConversionUtils;
import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.GameMode;
import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.utils.NamespacedKey;
import com.loohp.limbo.utils.NetworkEncryptionUtils;
import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.audience.MessageType;
import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.identity.Identity; import net.kyori.adventure.identity.Identity;
@ -63,7 +60,11 @@ import net.kyori.adventure.title.Title.Times;
import net.kyori.adventure.title.TitlePart; import net.kyori.adventure.title.TitlePart;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TranslatableComponent;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.UUID;
public class Player extends LivingEntity implements CommandSender { public class Player extends LivingEntity implements CommandSender {
@ -300,20 +301,23 @@ public class Player extends LivingEntity implements CommandSender {
} }
public void chat(String message, boolean verbose) { public void chat(String message, boolean verbose) {
chat(message, verbose, null, Instant.now());
}
public void chat(String message, boolean verbose, NetworkEncryptionUtils.SignatureData saltSignature, Instant time) {
if (Limbo.getInstance().getServerProperties().isAllowChat()) { if (Limbo.getInstance().getServerProperties().isAllowChat()) {
PlayerChatEvent event = (PlayerChatEvent) Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, CHAT_DEFAULT_FORMAT, message, false)); PlayerChatEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, CHAT_DEFAULT_FORMAT, message, false));
if (!event.isCancelled()) { if (!event.isCancelled()) {
if (hasPermission("limboserver.chat")) { if (hasPermission("limboserver.chat")) {
String chat = event.getFormat().replace("%name%", username).replace("%message%", event.getMessage()); String chat = event.getFormat().replace("%name%", username).replace("%message%", event.getMessage());
Limbo.getInstance().getConsole().sendMessage(chat); Limbo.getInstance().getConsole().sendMessage(chat);
if (event.getFormat().equals(CHAT_DEFAULT_FORMAT)) { if (event.getFormat().equals(CHAT_DEFAULT_FORMAT)) {
TranslatableComponent translatable = new TranslatableComponent("chat.type.text", username, event.getMessage());
for (Player each : Limbo.getInstance().getPlayers()) { for (Player each : Limbo.getInstance().getPlayers()) {
each.sendMessage(translatable, uuid); each.sendMessage(Identity.identity(uuid), Component.translatable("chat.type.text").args(Component.text(this.getName()), Component.text(event.getMessage())), MessageType.CHAT, saltSignature, time);
} }
} else { } else {
for (Player each : Limbo.getInstance().getPlayers()) { for (Player each : Limbo.getInstance().getPlayers()) {
each.sendMessage(chat, uuid); each.sendMessage(Identity.identity(uuid), Component.text(chat), MessageType.SYSTEM, saltSignature, time);
} }
} }
} else if (verbose) { } else if (verbose) {
@ -412,10 +416,29 @@ public class Player extends LivingEntity implements CommandSender {
@Override @Override
public void sendMessage(Identity source, Component message, MessageType type) { public void sendMessage(Identity source, Component message, MessageType type) {
sendMessage(source, message, type, null, Instant.now());
}
public void sendMessage(Identity source, Component message, MessageType type, NetworkEncryptionUtils.SignatureData signature, Instant time) {
try { try {
PacketPlayOutChat chat = new PacketPlayOutChat(message, 0, uuid); PacketOut chat;
switch (type) {
case CHAT:
/*
if (signature == null) {
chat = new ClientboundPlayerChatPacket(Component.empty(), Optional.of(message), 0, uuid, time, SignatureData.NONE);
} else {
chat = new ClientboundPlayerChatPacket(message, Optional.of(message), 0, uuid, time, signature);
}
break;
*/
case SYSTEM:
default:
chat = new ClientboundSystemChatPacket(message, 1);
break;
}
clientConnection.sendPacket(chat); clientConnection.sendPacket(chat);
} catch (IOException e) {} } catch (IOException ignored) {}
} }
@Override @Override
@ -446,9 +469,9 @@ public class Player extends LivingEntity implements CommandSender {
@Override @Override
public void sendActionBar(Component message) { public void sendActionBar(Component message) {
try { try {
PacketPlayOutChat chat = new PacketPlayOutChat(message, 2, new UUID(0, 0)); ClientboundSystemChatPacket chat = new ClientboundSystemChatPacket(message, 2);
clientConnection.sendPacket(chat); clientConnection.sendPacket(chat);
} catch (IOException e) {} } catch (IOException ignored) {}
} }
@Override @Override

View File

@ -19,6 +19,18 @@
package com.loohp.limbo.player; package com.loohp.limbo.player;
import com.loohp.limbo.Limbo;
import com.loohp.limbo.entity.Entity;
import com.loohp.limbo.location.Location;
import com.loohp.limbo.network.protocol.packets.ClientboundLevelChunkWithLightPacket;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutEntityDestroy;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutEntityMetadata;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutSpawnEntity;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutUnloadChunk;
import com.loohp.limbo.world.ChunkPosition;
import com.loohp.limbo.world.World;
import net.querz.mca.Chunk;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -29,20 +41,6 @@ import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.loohp.limbo.Limbo;
import com.loohp.limbo.entity.Entity;
import com.loohp.limbo.location.Location;
import com.loohp.limbo.network.protocol.packets.ClientboundLevelChunkWithLightPacket;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutEntityDestroy;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutEntityMetadata;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutSpawnEntity;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutSpawnEntityLiving;
import com.loohp.limbo.network.protocol.packets.PacketPlayOutUnloadChunk;
import com.loohp.limbo.world.ChunkPosition;
import com.loohp.limbo.world.World;
import net.querz.mca.Chunk;
public class PlayerInteractManager { public class PlayerInteractManager {
private Player player; private Player player;
@ -75,19 +73,11 @@ public class PlayerInteractManager {
Set<Entity> entitiesInRange = player.getWorld().getEntities().stream().filter(each -> each.getLocation().distanceSquared(location) < viewDistanceBlocks * viewDistanceBlocks).collect(Collectors.toSet()); Set<Entity> entitiesInRange = player.getWorld().getEntities().stream().filter(each -> each.getLocation().distanceSquared(location) < viewDistanceBlocks * viewDistanceBlocks).collect(Collectors.toSet());
for (Entity entity : entitiesInRange) { for (Entity entity : entitiesInRange) {
if (!entities.contains(entity)) { if (!entities.contains(entity)) {
if (entity.getType().isAlive()) { PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(entity.getEntityId(), entity.getUniqueId(), entity.getType(), entity.getX(), entity.getY(), entity.getZ(), entity.getYaw(), entity.getPitch(), entity.getPitch(), 0, (short) 0, (short) 0, (short) 0);
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(entity.getEntityId(), entity.getUniqueId(), entity.getType(), entity.getX(), entity.getY(), entity.getZ(), entity.getYaw(), entity.getPitch(), entity.getPitch(), (short) 0, (short) 0, (short) 0);
player.clientConnection.sendPacket(packet); player.clientConnection.sendPacket(packet);
PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity); PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity);
player.clientConnection.sendPacket(meta); player.clientConnection.sendPacket(meta);
} else {
PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(entity.getEntityId(), entity.getUniqueId(), entity.getType(), entity.getX(), entity.getY(), entity.getZ(), entity.getPitch(), entity.getYaw(), (short) 0, (short) 0, (short) 0);
player.clientConnection.sendPacket(packet);
PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity);
player.clientConnection.sendPacket(meta);
}
} }
} }
List<Integer> ids = new ArrayList<>(); List<Integer> ids = new ArrayList<>();

View File

@ -58,11 +58,10 @@ public class DeclareCommands {
i++; i++;
output.writeByte(2 | 0x04 | 0x10); output.writeByte(2 | 0x04 | 0x10);
DataTypeIO.writeVarInt(output, 1);
DataTypeIO.writeVarInt(output, i);
DataTypeIO.writeString(output, "arg", StandardCharsets.UTF_8);
DataTypeIO.writeString(output, "brigadier:string", StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, 0); DataTypeIO.writeVarInt(output, 0);
DataTypeIO.writeString(output, "arg", StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, 5); //brigadier:string
DataTypeIO.writeVarInt(output, 2);
DataTypeIO.writeString(output, "minecraft:ask_server", StandardCharsets.UTF_8); DataTypeIO.writeString(output, "minecraft:ask_server", StandardCharsets.UTF_8);
i++; i++;
} }

View File

@ -0,0 +1,84 @@
/*
* This file is part of Limbo.
*
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2022. Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.loohp.limbo.utils;
import com.google.common.primitives.Longs;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Map;
public class NetworkEncryptionUtils {
public static class SignatureData {
public static final SignatureData NONE = new SignatureData(0L, new byte[0]);
private long salt;
private byte[] signature;
public SignatureData(long salt, byte[] signature) {
this.salt = salt;
this.signature = signature;
}
public SignatureData(DataInputStream in) throws IOException {
this.salt = in.readLong();
int length = DataTypeIO.readVarInt(in);
this.signature = new byte[length];
in.readFully(this.signature);
}
public boolean isSignaturePresent() {
return this.signature.length > 0;
}
public static void write(DataOutputStream out, SignatureData signatureData) throws IOException {
out.writeLong(signatureData.salt);
DataTypeIO.writeVarInt(out, signatureData.signature.length);
out.write(signatureData.signature);
}
public byte[] getSalt() {
return Longs.toByteArray(this.salt);
}
}
public static class ArgumentSignatures {
private long salt;
private Map<String, byte[]> signatures;
public ArgumentSignatures(long salt, Map<String, byte[]> signatures) {
this.salt = salt;
this.signatures = signatures;
}
public long getSalt() {
return salt;
}
public Map<String, byte[]> getSignatures() {
return signatures;
}
}
}

View File

@ -57,7 +57,7 @@ public class DimensionRegistry {
this.reg = file; this.reg = file;
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(reg), StandardCharsets.UTF_8)) { try (InputStreamReader reader = new InputStreamReader(Files.newInputStream(reg.toPath()), StandardCharsets.UTF_8)) {
JSONObject json = (JSONObject) new JSONParser().parse(reader); JSONObject json = (JSONObject) new JSONParser().parse(reader);
CompoundTag tag = CustomNBTUtils.getCompoundTagFromJson((JSONObject) json.get("value")); CompoundTag tag = CustomNBTUtils.getCompoundTagFromJson((JSONObject) json.get("value"));
defaultTag = tag; defaultTag = tag;

View File

@ -26,6 +26,7 @@ import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
@ -79,7 +80,7 @@ public class GeneratedBlockDataMappings {
for (Object entry : (JSONArray) data.get("states")) { for (Object entry : (JSONArray) data.get("states")) {
JSONObject jsonobj = (JSONObject) entry; JSONObject jsonobj = (JSONObject) entry;
if (((JSONObject) jsonobj.get("properties")).keySet().stream().allMatch(key -> blockstate.get(key).equals((String) (((JSONObject) jsonobj.get("properties")).get(key))))) { if (((JSONObject) jsonobj.get("properties")).keySet().stream().allMatch(key -> Objects.equals(blockstate.get(key), ((JSONObject) jsonobj.get("properties")).get(key)))) {
return (int) (long) jsonobj.get("id"); return (int) (long) jsonobj.get("id");
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -12,44 +12,45 @@
"PacketLoginOutPluginMessaging": "0x04" "PacketLoginOutPluginMessaging": "0x04"
}, },
"PlayIn": { "PlayIn": {
"0x0F": "PacketPlayInKeepAlive", "0x11": "PacketPlayInKeepAlive",
"0x03": "PacketPlayInChat", "0x03": "ServerboundChatCommandPacket",
"0x12": "PacketPlayInPositionAndLook", "0x04": "PacketPlayInChat",
"0x11": "PacketPlayInPosition", "0x14": "PacketPlayInPositionAndLook",
"0x13": "PacketPlayInRotation", "0x13": "PacketPlayInPosition",
"0x0A": "PacketPlayInPluginMessaging", "0x15": "PacketPlayInRotation",
"0x06": "PacketPlayInTabComplete", "0x0C": "PacketPlayInPluginMessaging",
"0x25": "PacketPlayInHeldItemChange", "0x08": "PacketPlayInTabComplete",
"0x21": "PacketPlayInResourcePackStatus" "0x27": "PacketPlayInHeldItemChange",
"0x23": "PacketPlayInResourcePackStatus"
}, },
"PlayOut": { "PlayOut": {
"PacketPlayOutLogin": "0x26", "PacketPlayOutLogin": "0x23",
"PacketPlayOutPositionAndLook": "0x38", "PacketPlayOutPositionAndLook": "0x36",
"PacketPlayOutSpawnPosition": "0x4B", "PacketPlayOutSpawnPosition": "0x4A",
"PacketPlayOutChat": "0x0F", "ClientboundPlayerChatPacket": "0x30",
"PacketPlayOutPlayerAbilities": "0x32", "ClientboundSystemChatPacket": "0x5F",
"ClientboundLevelChunkWithLightPacket": "0x22", "PacketPlayOutPlayerAbilities": "0x2F",
"PacketPlayOutUnloadChunk": "0x1D", "ClientboundLevelChunkWithLightPacket": "0x1F",
"PacketPlayOutKeepAlive": "0x21", "PacketPlayOutUnloadChunk": "0x1A",
"PacketPlayOutPlayerInfo": "0x36", "PacketPlayOutKeepAlive": "0x1E",
"PacketPlayOutUpdateViewPosition": "0x49", "PacketPlayOutPlayerInfo": "0x34",
"PacketPlayOutDisconnect": "0x1A", "PacketPlayOutUpdateViewPosition": "0x48",
"PacketPlayOutPluginMessaging": "0x18", "PacketPlayOutDisconnect": "0x17",
"PacketPlayOutTabComplete": "0x11", "PacketPlayOutPluginMessaging": "0x15",
"PacketPlayOutDeclareCommands": "0x12", "PacketPlayOutTabComplete": "0x0E",
"PacketPlayOutRespawn": "0x3D", "PacketPlayOutDeclareCommands": "0x0F",
"PacketPlayOutGameState": "0x1E", "PacketPlayOutRespawn": "0x3B",
"PacketPlayOutEntityDestroy": "0x3A", "PacketPlayOutGameState": "0x1B",
"PacketPlayOutEntityDestroy": "0x38",
"PacketPlayOutEntityMetadata": "0x4D", "PacketPlayOutEntityMetadata": "0x4D",
"PacketPlayOutSpawnEntity": "0x00", "PacketPlayOutSpawnEntity": "0x00",
"PacketPlayOutSpawnEntityLiving": "0x02", "PacketPlayOutHeldItemChange": "0x47",
"PacketPlayOutHeldItemChange": "0x48", "PacketPlayOutPlayerListHeaderFooter": "0x60",
"PacketPlayOutPlayerListHeaderFooter": "0x5F", "PacketPlayOutResourcePackSend": "0x3A",
"PacketPlayOutResourcePackSend": "0x3C",
"ClientboundSetTitlesAnimationPacket": "0x5B", "ClientboundSetTitlesAnimationPacket": "0x5B",
"ClientboundSetTitleTextPacket": "0x5A", "ClientboundSetTitleTextPacket": "0x5A",
"ClientboundSetSubtitleTextPacket": "0x58", "ClientboundSetSubtitleTextPacket": "0x58",
"ClientboundClearTitlesPacket": "0x10" "ClientboundClearTitlesPacket": "0x0D"
}, },
"StatusIn": { "StatusIn": {
"0x01": "PacketStatusInPing", "0x01": "PacketStatusInPing",

File diff suppressed because it is too large Load Diff