diff --git a/pom.xml b/pom.xml
index 8d394d4..7d31938 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,6 +10,9 @@
4.1.6.Final
+ 1.16.12
+ 1.2.29
+ 4.12
@@ -18,6 +21,25 @@
netty-all
${netty-all.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+ com.alibaba
+ fastjson
+ ${fastjson.version}
+
+
+
+ junit
+ junit
+ ${junit.version}
+
+
diff --git a/src/main/java/the/flash/protocol/command/Command.java b/src/main/java/the/flash/protocol/command/Command.java
new file mode 100644
index 0000000..31b3d26
--- /dev/null
+++ b/src/main/java/the/flash/protocol/command/Command.java
@@ -0,0 +1,6 @@
+package the.flash.protocol.command;
+
+public interface Command {
+
+ Byte LOGIN_REQUEST = 1;
+}
diff --git a/src/main/java/the/flash/protocol/command/LoginRequestPacket.java b/src/main/java/the/flash/protocol/command/LoginRequestPacket.java
new file mode 100644
index 0000000..d24753b
--- /dev/null
+++ b/src/main/java/the/flash/protocol/command/LoginRequestPacket.java
@@ -0,0 +1,19 @@
+package the.flash.protocol.command;
+
+import lombok.Data;
+
+import static the.flash.protocol.command.Command.LOGIN_REQUEST;
+
+@Data
+public class LoginRequestPacket extends Packet {
+ private Integer userId;
+
+ private String username;
+
+ private String password;
+
+ @Override
+ public Byte getCommand() {
+ return LOGIN_REQUEST;
+ }
+}
diff --git a/src/main/java/the/flash/protocol/command/Packet.java b/src/main/java/the/flash/protocol/command/Packet.java
new file mode 100644
index 0000000..c4a5945
--- /dev/null
+++ b/src/main/java/the/flash/protocol/command/Packet.java
@@ -0,0 +1,17 @@
+package the.flash.protocol.command;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+
+@Data
+public abstract class Packet {
+ /**
+ * 协议版本
+ */
+ @JSONField(deserialize = false, serialize = false)
+ private Byte version = 1;
+
+
+ @JSONField(serialize = false)
+ public abstract Byte getCommand();
+}
diff --git a/src/main/java/the/flash/protocol/command/PacketCodeC.java b/src/main/java/the/flash/protocol/command/PacketCodeC.java
new file mode 100644
index 0000000..d70f787
--- /dev/null
+++ b/src/main/java/the/flash/protocol/command/PacketCodeC.java
@@ -0,0 +1,85 @@
+package the.flash.protocol.command;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
+import the.flash.serialize.Serializer;
+import the.flash.serialize.impl.JSONSerializer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static the.flash.protocol.command.Command.LOGIN_REQUEST;
+
+public class PacketCodeC {
+
+ private static final int MAGIC_NUMBER = 0x1234;
+ private static final Map> packetTypeMap;
+ private static final Map serializerMap;
+
+ static {
+ packetTypeMap = new HashMap<>();
+ packetTypeMap.put(LOGIN_REQUEST, LoginRequestPacket.class);
+
+ serializerMap = new HashMap<>();
+ Serializer serializer = new JSONSerializer();
+ serializerMap.put(serializer.getSerializerAlogrithm(), serializer);
+ }
+
+
+ public ByteBuf encode(Packet packet) {
+ // 1. 创建 ByteBuf 对象
+ ByteBuf byteBuf = ByteBufAllocator.DEFAULT.ioBuffer();
+ // 2. 序列化 java 对象
+ byte[] bytes = Serializer.DEFAULT.serialize(packet);
+
+ // 3. 实际编码过程
+ byteBuf.writeInt(MAGIC_NUMBER);
+ byteBuf.writeByte(packet.getVersion());
+ byteBuf.writeByte(Serializer.DEFAULT.getSerializerAlogrithm());
+ byteBuf.writeByte(packet.getCommand());
+ byteBuf.writeInt(bytes.length);
+ byteBuf.writeBytes(bytes);
+
+ return byteBuf;
+ }
+
+
+ public Packet decode(ByteBuf byteBuf) {
+ // 跳过 magic number
+ byteBuf.skipBytes(4);
+
+ // 跳过版本号
+ byteBuf.skipBytes(1);
+
+ // 序列化算法
+ byte serializeAlgorithm = byteBuf.readByte();
+
+ // 指令
+ byte command = byteBuf.readByte();
+
+ // 数据包长度
+ int length = byteBuf.readInt();
+
+ byte[] bytes = new byte[length];
+ byteBuf.readBytes(bytes);
+
+ Class extends Packet> requestType = getRequestType(command);
+ Serializer serializer = getSerializer(serializeAlgorithm);
+
+ if (requestType != null && serializer != null) {
+ return serializer.deserialize(requestType, bytes);
+ }
+
+ return null;
+ }
+
+ private Serializer getSerializer(byte serializeAlgorithm) {
+
+ return serializerMap.get(serializeAlgorithm);
+ }
+
+ private Class extends Packet> getRequestType(byte command) {
+
+ return packetTypeMap.get(command);
+ }
+}
diff --git a/src/main/java/the/flash/serialize/Serializer.java b/src/main/java/the/flash/serialize/Serializer.java
new file mode 100644
index 0000000..6abe22b
--- /dev/null
+++ b/src/main/java/the/flash/serialize/Serializer.java
@@ -0,0 +1,25 @@
+package the.flash.serialize;
+
+import the.flash.serialize.impl.JSONSerializer;
+
+public interface Serializer {
+
+ Serializer DEFAULT = new JSONSerializer();
+
+ /**
+ * 序列化算法
+ * @return
+ */
+ byte getSerializerAlogrithm();
+
+ /**
+ * java 对象转换成二进制
+ */
+ byte[] serialize(Object object);
+
+ /**
+ * 二进制转换成 java 对象
+ */
+ T deserialize(Class clazz, byte[] bytes);
+
+}
diff --git a/src/main/java/the/flash/serialize/SerializerAlogrithm.java b/src/main/java/the/flash/serialize/SerializerAlogrithm.java
new file mode 100644
index 0000000..0108ead
--- /dev/null
+++ b/src/main/java/the/flash/serialize/SerializerAlogrithm.java
@@ -0,0 +1,8 @@
+package the.flash.serialize;
+
+public interface SerializerAlogrithm {
+ /**
+ * json 序列化
+ */
+ byte JSON = 1;
+}
diff --git a/src/main/java/the/flash/serialize/impl/JSONSerializer.java b/src/main/java/the/flash/serialize/impl/JSONSerializer.java
new file mode 100644
index 0000000..251f141
--- /dev/null
+++ b/src/main/java/the/flash/serialize/impl/JSONSerializer.java
@@ -0,0 +1,25 @@
+package the.flash.serialize.impl;
+
+import com.alibaba.fastjson.JSON;
+import the.flash.serialize.Serializer;
+import the.flash.serialize.SerializerAlogrithm;
+
+public class JSONSerializer implements Serializer {
+
+ @Override
+ public byte getSerializerAlogrithm() {
+ return SerializerAlogrithm.JSON;
+ }
+
+ @Override
+ public byte[] serialize(Object object) {
+
+ return JSON.toJSONBytes(object);
+ }
+
+ @Override
+ public T deserialize(Class clazz, byte[] bytes) {
+
+ return JSON.parseObject(bytes, clazz);
+ }
+}
diff --git a/src/test/java/the/flash/protocol/command/PacketCodeCTest.java b/src/test/java/the/flash/protocol/command/PacketCodeCTest.java
new file mode 100644
index 0000000..8e51cbd
--- /dev/null
+++ b/src/test/java/the/flash/protocol/command/PacketCodeCTest.java
@@ -0,0 +1,28 @@
+package the.flash.protocol.command;
+
+import io.netty.buffer.ByteBuf;
+import org.junit.Assert;
+import org.junit.Test;
+import the.flash.serialize.Serializer;
+import the.flash.serialize.impl.JSONSerializer;
+
+public class PacketCodeCTest {
+ @Test
+ public void encode() {
+
+ Serializer serializer = new JSONSerializer();
+ LoginRequestPacket loginRequestPacket = new LoginRequestPacket();
+
+ loginRequestPacket.setVersion(((byte) 1));
+ loginRequestPacket.setUserId(123);
+ loginRequestPacket.setUsername("zhangsan");
+ loginRequestPacket.setPassword("password");
+
+ PacketCodeC packetCodeC = new PacketCodeC();
+ ByteBuf byteBuf = packetCodeC.encode(loginRequestPacket);
+ Packet decodedPacket = packetCodeC.decode(byteBuf);
+
+ Assert.assertArrayEquals(serializer.serialize(loginRequestPacket), serializer.serialize(decodedPacket));
+
+ }
+}