Skip to content

Commit 50c9942

Browse files
committed
feat: merge protocol extension
1 parent 8af145f commit 50c9942

32 files changed

Lines changed: 1341 additions & 11 deletions
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.cloudburstmc.protocol.bedrock.annotation;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
/**
9+
* Marks packets or packet fields that only exist on the NetEase edition protocol.
10+
*/
11+
@Retention(RetentionPolicy.RUNTIME)
12+
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.RECORD_COMPONENT})
13+
public @interface NetEaseOnly {
14+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.cloudburstmc.protocol.bedrock.codec.netease.serializer;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
5+
import org.cloudburstmc.protocol.bedrock.codec.BedrockPacketSerializer;
6+
import org.cloudburstmc.protocol.bedrock.packet.ConfirmSkinPacket;
7+
8+
public class ConfirmSkinSerializer implements BedrockPacketSerializer<ConfirmSkinPacket> {
9+
public static final ConfirmSkinSerializer INSTANCE = new ConfirmSkinSerializer();
10+
11+
@Override
12+
public void serialize(ByteBuf buffer, BedrockCodecHelper helper, ConfirmSkinPacket packet) {
13+
helper.writeArray(buffer, packet.getEntries(), (buf, h, entry) -> {
14+
buf.writeBoolean(entry.isValid());
15+
h.writeUuid(buf, entry.getUuid());
16+
h.writeByteArray(buf, entry.getSkinBytes());
17+
});
18+
19+
for (ConfirmSkinPacket.SkinEntry entry : packet.getEntries()) {
20+
String uidStr = entry.getUidStr();
21+
helper.writeString(buffer, uidStr != null ? uidStr : "");
22+
}
23+
24+
for (ConfirmSkinPacket.SkinEntry entry : packet.getEntries()) {
25+
String geoStr = entry.getGeoStr();
26+
helper.writeString(buffer, geoStr != null ? geoStr : "");
27+
}
28+
}
29+
30+
@Override
31+
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, ConfirmSkinPacket packet) {
32+
helper.readArray(buffer, packet.getEntries(), (buf, h) -> {
33+
ConfirmSkinPacket.SkinEntry entry = new ConfirmSkinPacket.SkinEntry();
34+
entry.setValid(buf.readBoolean());
35+
entry.setUuid(h.readUuid(buf));
36+
entry.setSkinBytes(h.readByteArray(buf));
37+
return entry;
38+
});
39+
40+
for (ConfirmSkinPacket.SkinEntry entry : packet.getEntries()) {
41+
entry.setUidStr(helper.readString(buffer));
42+
}
43+
44+
for (ConfirmSkinPacket.SkinEntry entry : packet.getEntries()) {
45+
entry.setGeoStr(helper.readString(buffer));
46+
}
47+
}
48+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.cloudburstmc.protocol.bedrock.codec.netease.serializer;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
5+
import org.cloudburstmc.protocol.bedrock.codec.BedrockPacketSerializer;
6+
import org.cloudburstmc.protocol.bedrock.packet.NetEaseJsonPacket;
7+
8+
public class NetEaseJsonSerializer implements BedrockPacketSerializer<NetEaseJsonPacket> {
9+
public static final NetEaseJsonSerializer INSTANCE = new NetEaseJsonSerializer();
10+
11+
@Override
12+
public void serialize(ByteBuf buffer, BedrockCodecHelper helper, NetEaseJsonPacket packet) {
13+
helper.writeString(buffer, packet.getJson());
14+
}
15+
16+
@Override
17+
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, NetEaseJsonPacket packet) {
18+
packet.setJson(helper.readString(buffer));
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package org.cloudburstmc.protocol.bedrock.codec.netease.serializer;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
5+
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
6+
import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.PlayerEnchantOptionsSerializer_v407;
7+
import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantData;
8+
import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantOptionData;
9+
import org.cloudburstmc.protocol.bedrock.util.VarInts;
10+
11+
import java.util.List;
12+
13+
public class PlayerEnchantOptionsSerializer_v407_NetEase extends PlayerEnchantOptionsSerializer_v407 {
14+
public static final PlayerEnchantOptionsSerializer_v407_NetEase INSTANCE = new PlayerEnchantOptionsSerializer_v407_NetEase();
15+
16+
@Override
17+
protected void writeOption(ByteBuf buffer, BedrockCodecHelper helper, EnchantOptionData option) {
18+
VarInts.writeUnsignedInt(buffer, option.cost());
19+
buffer.writeIntLE(option.primarySlot());
20+
helper.writeArray(buffer, option.enchants0(), (b, enchant) -> serializeEnchant(b, enchant, helper));
21+
helper.writeArray(buffer, option.enchants1(), (b, enchant) -> serializeEnchant(b, enchant, helper));
22+
helper.writeArray(buffer, option.enchants2(), (b, enchant) -> serializeEnchant(b, enchant, helper));
23+
helper.writeArray(buffer, option.enchantsCustom(), (b, enchant) -> serializeEnchant(b, enchant, helper));
24+
helper.writeString(buffer, option.enchantName());
25+
VarInts.writeUnsignedInt(buffer, option.enchantNetId());
26+
}
27+
28+
@Override
29+
protected EnchantOptionData readOption(ByteBuf buffer, BedrockCodecHelper helper) {
30+
int cost = VarInts.readUnsignedInt(buffer);
31+
int primarySlot = buffer.readIntLE();
32+
List<EnchantData> enchants0 = new ObjectArrayList<>();
33+
helper.readArray(buffer, enchants0, b -> deserializeEnchant(b, helper));
34+
List<EnchantData> enchants1 = new ObjectArrayList<>();
35+
helper.readArray(buffer, enchants1, b -> deserializeEnchant(b, helper));
36+
List<EnchantData> enchants2 = new ObjectArrayList<>();
37+
helper.readArray(buffer, enchants2, b -> deserializeEnchant(b, helper));
38+
List<EnchantData> enchantsCustom = new ObjectArrayList<>();
39+
helper.readArray(buffer, enchantsCustom, b -> deserializeEnchant(b, helper));
40+
String enchantName = helper.readString(buffer);
41+
int enchantNetId = VarInts.readUnsignedInt(buffer);
42+
return new EnchantOptionData(cost, primarySlot, enchants0, enchants1, enchants2, enchantsCustom, enchantName, enchantNetId);
43+
}
44+
45+
protected void serializeEnchant(ByteBuf buffer, EnchantData enchant, BedrockCodecHelper helper) {
46+
buffer.writeByte(enchant.type());
47+
buffer.writeByte(enchant.level());
48+
helper.writeString(buffer, enchant.modEnchantIdentifier());
49+
}
50+
51+
protected EnchantData deserializeEnchant(ByteBuf buffer, BedrockCodecHelper helper) {
52+
int type = buffer.readUnsignedByte();
53+
int level = buffer.readUnsignedByte();
54+
String modEnchantIdentifier = helper.readString(buffer);
55+
return new EnchantData(type, level, modEnchantIdentifier);
56+
}
57+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.cloudburstmc.protocol.bedrock.codec.netease.serializer;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
5+
import org.cloudburstmc.protocol.bedrock.codec.BedrockPacketSerializer;
6+
import org.cloudburstmc.protocol.bedrock.packet.PyRpcPacket;
7+
8+
public class PyRpcSerializer implements BedrockPacketSerializer<PyRpcPacket> {
9+
public static final PyRpcSerializer INSTANCE = new PyRpcSerializer();
10+
11+
@Override
12+
public void serialize(ByteBuf buffer, BedrockCodecHelper helper, PyRpcPacket packet) {
13+
helper.writeByteArray(buffer, packet.getData());
14+
buffer.writeIntLE((int) packet.getMsgId());
15+
}
16+
17+
@Override
18+
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, PyRpcPacket packet) {
19+
packet.setData(helper.readByteArray(buffer));
20+
packet.setMsgId(buffer.readUnsignedIntLE());
21+
}
22+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.cloudburstmc.protocol.bedrock.codec.netease.serializer;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
5+
import org.cloudburstmc.protocol.bedrock.codec.BedrockPacketSerializer;
6+
import org.cloudburstmc.protocol.bedrock.packet.StoreBuySuccessPacket;
7+
8+
public class StoreBuySuccessSerializer implements BedrockPacketSerializer<StoreBuySuccessPacket> {
9+
public static final StoreBuySuccessSerializer INSTANCE = new StoreBuySuccessSerializer();
10+
11+
@Override
12+
public void serialize(ByteBuf buffer, BedrockCodecHelper helper, StoreBuySuccessPacket packet) {
13+
}
14+
15+
@Override
16+
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, StoreBuySuccessPacket packet) {
17+
}
18+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package org.cloudburstmc.protocol.bedrock.codec.v630_netease;
2+
3+
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
4+
import org.cloudburstmc.protocol.bedrock.codec.netease.serializer.ConfirmSkinSerializer;
5+
import org.cloudburstmc.protocol.bedrock.codec.netease.serializer.NetEaseJsonSerializer;
6+
import org.cloudburstmc.protocol.bedrock.codec.netease.serializer.PlayerEnchantOptionsSerializer_v407_NetEase;
7+
import org.cloudburstmc.protocol.bedrock.codec.netease.serializer.PyRpcSerializer;
8+
import org.cloudburstmc.protocol.bedrock.codec.netease.serializer.StoreBuySuccessSerializer;
9+
import org.cloudburstmc.protocol.bedrock.codec.v575.BedrockCodecHelper_v575;
10+
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
11+
import org.cloudburstmc.protocol.bedrock.codec.v630_netease.serializer.PlayerAuthInputSerializer_v630_NetEase;
12+
import org.cloudburstmc.protocol.bedrock.codec.v630_netease.serializer.TextSerializer_v630_NetEase;
13+
import org.cloudburstmc.protocol.bedrock.data.PacketRecipient;
14+
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
15+
import org.cloudburstmc.protocol.bedrock.packet.ConfirmSkinPacket;
16+
import org.cloudburstmc.protocol.bedrock.packet.NetEaseJsonPacket;
17+
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
18+
import org.cloudburstmc.protocol.bedrock.packet.PlayerEnchantOptionsPacket;
19+
import org.cloudburstmc.protocol.bedrock.packet.PyRpcPacket;
20+
import org.cloudburstmc.protocol.bedrock.packet.StoreBuySuccessPacket;
21+
import org.cloudburstmc.protocol.bedrock.packet.TextPacket;
22+
import org.cloudburstmc.protocol.bedrock.util.TypeMap;
23+
24+
public class Bedrock_v630_NetEase extends Bedrock_v630 {
25+
protected static final TypeMap<ContainerSlotType> CONTAINER_SLOT_TYPES = Bedrock_v630.CONTAINER_SLOT_TYPES
26+
.toBuilder()
27+
.shift(17, 1)
28+
.insert(17, ContainerSlotType.RECIPE_CUSTOM)
29+
.build();
30+
31+
public static final BedrockCodec CODEC = Bedrock_v630.CODEC.toBuilder()
32+
.raknetProtocolVersion(8)
33+
.helper(() -> new BedrockCodecHelper_v575(ENTITY_DATA, GAME_RULE_TYPES, ITEM_STACK_REQUEST_TYPES, CONTAINER_SLOT_TYPES, PLAYER_ABILITIES, TEXT_PROCESSING_ORIGINS))
34+
.updateSerializer(PlayerAuthInputPacket.class, PlayerAuthInputSerializer_v630_NetEase.INSTANCE)
35+
.updateSerializer(TextPacket.class, TextSerializer_v630_NetEase.INSTANCE)
36+
.updateSerializer(PlayerEnchantOptionsPacket.class, PlayerEnchantOptionsSerializer_v407_NetEase.INSTANCE)
37+
.registerPacket(PyRpcPacket::new, PyRpcSerializer.INSTANCE, 200, PacketRecipient.BOTH)
38+
.registerPacket(StoreBuySuccessPacket::new, StoreBuySuccessSerializer.INSTANCE, 202, PacketRecipient.BOTH)
39+
.registerPacket(NetEaseJsonPacket::new, NetEaseJsonSerializer.INSTANCE, 203, PacketRecipient.BOTH)
40+
.registerPacket(ConfirmSkinPacket::new, ConfirmSkinSerializer.INSTANCE, 228, PacketRecipient.CLIENT)
41+
.build();
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package org.cloudburstmc.protocol.bedrock.codec.v630_netease.serializer;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import org.cloudburstmc.math.vector.Vector2f;
5+
import org.cloudburstmc.math.vector.Vector3f;
6+
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
7+
import org.cloudburstmc.protocol.bedrock.codec.v575.serializer.PlayerAuthInputSerializer_v575;
8+
import org.cloudburstmc.protocol.bedrock.data.PlayerAuthInputData;
9+
import org.cloudburstmc.protocol.bedrock.data.PlayerBlockActionData;
10+
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
11+
import org.cloudburstmc.protocol.bedrock.util.VarInts;
12+
13+
public class PlayerAuthInputSerializer_v630_NetEase extends PlayerAuthInputSerializer_v575 {
14+
public static final PlayerAuthInputSerializer_v630_NetEase INSTANCE = new PlayerAuthInputSerializer_v630_NetEase();
15+
16+
@Override
17+
public void serialize(ByteBuf buffer, BedrockCodecHelper helper, PlayerAuthInputPacket packet) {
18+
Vector3f rotation = packet.getRotation();
19+
buffer.writeFloatLE(rotation.getX());
20+
buffer.writeFloatLE(rotation.getY());
21+
helper.writeVector3f(buffer, packet.getPosition());
22+
buffer.writeFloatLE(packet.getMotion().getX());
23+
buffer.writeFloatLE(packet.getMotion().getY());
24+
buffer.writeFloatLE(rotation.getZ());
25+
long flagValue = 0;
26+
for (PlayerAuthInputData data : packet.getInputData()) {
27+
flagValue |= 1L << data.ordinal();
28+
}
29+
VarInts.writeUnsignedLong(buffer, flagValue);
30+
VarInts.writeUnsignedInt(buffer, packet.getInputMode().ordinal());
31+
VarInts.writeUnsignedInt(buffer, packet.getPlayMode().ordinal());
32+
writeInteractionModel(buffer, helper, packet);
33+
helper.writeVector2f(buffer, packet.getInteractRotation());
34+
VarInts.writeUnsignedLong(buffer, packet.getTick());
35+
helper.writeVector3f(buffer, packet.getDelta());
36+
buffer.writeBoolean(packet.isCameraDeparted());
37+
38+
if (packet.getInputData().contains(PlayerAuthInputData.PERFORM_ITEM_INTERACTION)) {
39+
writeItemUseTransaction(buffer, helper, packet.getItemUseTransaction());
40+
}
41+
if (packet.getInputData().contains(PlayerAuthInputData.PERFORM_ITEM_STACK_REQUEST)) {
42+
helper.writeItemStackRequest(buffer, packet.getItemStackRequest());
43+
}
44+
if (packet.getInputData().contains(PlayerAuthInputData.PERFORM_BLOCK_ACTIONS)) {
45+
VarInts.writeInt(buffer, packet.getPlayerActions().size());
46+
for (PlayerBlockActionData actionData : packet.getPlayerActions()) {
47+
writePlayerBlockActionData(buffer, helper, actionData);
48+
}
49+
}
50+
helper.writeVector2f(buffer, packet.getAnalogMoveVector());
51+
}
52+
53+
@Override
54+
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, PlayerAuthInputPacket packet) {
55+
float x = buffer.readFloatLE();
56+
float y = buffer.readFloatLE();
57+
packet.setPosition(helper.readVector3f(buffer));
58+
packet.setMotion(Vector2f.from(buffer.readFloatLE(), buffer.readFloatLE()));
59+
float z = buffer.readFloatLE();
60+
packet.setRotation(Vector3f.from(x, y, z));
61+
long flagValue = VarInts.readUnsignedLong(buffer);
62+
for (PlayerAuthInputData flag : PlayerAuthInputData.values()) {
63+
if ((flagValue & (1L << flag.ordinal())) != 0) {
64+
packet.getInputData().add(flag);
65+
}
66+
}
67+
packet.setInputMode(INPUT_MODES[VarInts.readUnsignedInt(buffer)]);
68+
packet.setPlayMode(CLIENT_PLAY_MODES[VarInts.readUnsignedInt(buffer)]);
69+
readInteractionModel(buffer, helper, packet);
70+
packet.setInteractRotation(helper.readVector2f(buffer));
71+
packet.setTick(VarInts.readUnsignedLong(buffer));
72+
packet.setDelta(helper.readVector3f(buffer));
73+
packet.setCameraDeparted(buffer.readBoolean());
74+
75+
if (packet.getInputData().contains(PlayerAuthInputData.PERFORM_ITEM_INTERACTION)) {
76+
packet.setItemUseTransaction(readItemUseTransaction(buffer, helper));
77+
}
78+
if (packet.getInputData().contains(PlayerAuthInputData.PERFORM_ITEM_STACK_REQUEST)) {
79+
packet.setItemStackRequest(helper.readItemStackRequest(buffer));
80+
}
81+
if (packet.getInputData().contains(PlayerAuthInputData.PERFORM_BLOCK_ACTIONS)) {
82+
helper.readArray(buffer, packet.getPlayerActions(), VarInts::readInt, this::readPlayerBlockActionData, 32);
83+
}
84+
packet.setAnalogMoveVector(helper.readVector2f(buffer));
85+
}
86+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.cloudburstmc.protocol.bedrock.codec.v630_netease.serializer;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
5+
import org.cloudburstmc.protocol.bedrock.codec.v554.serializer.TextSerializer_v554;
6+
import org.cloudburstmc.protocol.bedrock.packet.TextPacket;
7+
8+
public class TextSerializer_v630_NetEase extends TextSerializer_v554 {
9+
public static final TextSerializer_v630_NetEase INSTANCE = new TextSerializer_v630_NetEase();
10+
11+
@Override
12+
public void serialize(ByteBuf buffer, BedrockCodecHelper helper, TextPacket packet) {
13+
super.serialize(buffer, helper, packet);
14+
15+
TextPacket.Type type = packet.getType();
16+
if (type == TextPacket.Type.CHAT || type == TextPacket.Type.POPUP) {
17+
helper.writeString(buffer, packet.getUnknown());
18+
}
19+
}
20+
21+
@Override
22+
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, TextPacket packet) {
23+
super.deserialize(buffer, helper, packet);
24+
25+
TextPacket.Type type = packet.getType();
26+
if (type == TextPacket.Type.CHAT || type == TextPacket.Type.POPUP) {
27+
packet.setUnknown(helper.readString(buffer));
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)