package com.nukkitx.protocol.bedrock.v332.serializer; import com.nukkitx.network.VarInts; import com.nukkitx.protocol.bedrock.data.CraftingData; import com.nukkitx.protocol.bedrock.data.CraftingType; import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.packet.CraftingDataPacket; import com.nukkitx.protocol.bedrock.v332.BedrockUtils; import com.nukkitx.protocol.serializer.PacketSerializer; import io.netty.buffer.ByteBuf; import lombok.AccessLevel; import lombok.NoArgsConstructor; import java.util.UUID; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class CraftingDataSerializer_v332 implements PacketSerializer<CraftingDataPacket> { public static final CraftingDataSerializer_v332 INSTANCE = new CraftingDataSerializer_v332(); @Override public void serialize(ByteBuf buffer, CraftingDataPacket packet) { BedrockUtils.writeArray(buffer, packet.getCraftingData(), (buf, craftingData) -> { VarInts.writeInt(buf, craftingData.getType().ordinal()); switch (craftingData.getType()) { case SHAPELESS: case SHAPELESS_CHEMISTRY: case SHULKER_BOX: BedrockUtils.writeArray(buf, craftingData.getInputs(), BedrockUtils::writeItemData); BedrockUtils.writeArray(buf, craftingData.getOutputs(), BedrockUtils::writeItemData); BedrockUtils.writeUuid(buf, craftingData.getUuid()); break; case SHAPED: case SHAPED_CHEMISTRY: VarInts.writeInt(buf, craftingData.getWidth()); VarInts.writeInt(buf, craftingData.getHeight()); int count = craftingData.getWidth() * craftingData.getHeight(); ItemData[] inputs = craftingData.getInputs(); for (int i = 0; i < count; i++) { BedrockUtils.writeItemData(buf, inputs[i]); } BedrockUtils.writeArray(buf, craftingData.getOutputs(), BedrockUtils::writeItemData); BedrockUtils.writeUuid(buf, craftingData.getUuid()); break; case FURNACE: case FURNACE_DATA: VarInts.writeInt(buf, craftingData.getInputId()); if (craftingData.getType() == CraftingType.FURNACE_DATA) { VarInts.writeInt(buf, craftingData.getInputDamage()); } BedrockUtils.writeItemData(buf, craftingData.getOutputs()[0]); break; case MULTI: BedrockUtils.writeUuid(buf, craftingData.getUuid()); break; } }); buffer.writeBoolean(packet.isCleanRecipes()); } @Override public void deserialize(ByteBuf buffer, CraftingDataPacket packet) { BedrockUtils.readArray(buffer, packet.getCraftingData(), buf -> { int typeInt = VarInts.readInt(buf); CraftingType type = CraftingType.byId(typeInt); if (type == null) { // TODO: 23/04/19 log type return null; } switch (type) { case SHAPELESS: case SHAPELESS_CHEMISTRY: case SHULKER_BOX: int inputCount = VarInts.readUnsignedInt(buf); ItemData[] inputs = new ItemData[inputCount]; for (int i = 0; i < inputCount; i++) { inputs[i] = BedrockUtils.readItemData(buf); } int outputCount = VarInts.readUnsignedInt(buf); ItemData[] outputs = new ItemData[outputCount]; for (int i = 0; i < outputCount; i++) { outputs[i] = BedrockUtils.readItemData(buf); } UUID uuid = BedrockUtils.readUuid(buf); return new CraftingData(type, -1, -1, -1, -1, inputs, outputs, uuid, null); case SHAPED: case SHAPED_CHEMISTRY: int width = VarInts.readInt(buf); int height = VarInts.readInt(buf); int inputCount2 = width * height; ItemData[] inputs2 = new ItemData[inputCount2]; for (int i = 0; i < inputCount2; i++) { inputs2[i] = BedrockUtils.readItemData(buf); } int outputCount2 = VarInts.readUnsignedInt(buf); ItemData[] outputs2 = new ItemData[outputCount2]; for (int i = 0; i < outputCount2; i++) { outputs2[i] = BedrockUtils.readItemData(buf); } UUID uuid2 = BedrockUtils.readUuid(buf); return new CraftingData(type, width, height, -1, -1, inputs2, outputs2, uuid2, null); case FURNACE: case FURNACE_DATA: int inputId = VarInts.readInt(buf); int inputDamage = type == CraftingType.FURNACE_DATA ? VarInts.readInt(buf) : -1; ItemData[] output = new ItemData[]{BedrockUtils.readItemData(buf)}; return new CraftingData(type, -1, -1, inputId, inputDamage, null, output, null, null); case MULTI: UUID uuid3 = BedrockUtils.readUuid(buf); return CraftingData.fromMulti(uuid3); } throw new IllegalArgumentException("Unhandled crafting data type: " + type); }); packet.setCleanRecipes(buffer.readBoolean()); } }