diff --git a/mirai-core/src/main/java/net/mamoe/mirai/message/FaceID.java b/mirai-core/src/main/java/net/mamoe/mirai/message/FaceID.java
index 506a23002..3a8831860 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/message/FaceID.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/message/FaceID.java
@@ -4,8 +4,147 @@ package net.mamoe.mirai.message;
  * @author Him188moe
  */
 public enum FaceID {
-    // TODO: 2019/9/1
+    Face_jingya(0),
+    Face_piezui(1),
+    Face_se(2),
+    Face_fadai(3),
+    Face_deyi(4),
+    Face_liulei(5),
+    Face_haixiu(6),
+    Face_bizui(7),
+    Face_shui(8),
+    Face_daku(9),
+    Face_ganga(10),
+    Face_fanu(11),
+    Face_tiaopi(12),
+    Face_ciya(13),
+    Face_weixiao(14),
+    Face_nanguo(15),
+    Face_ku(16),
+    Face_zhuakuang(18),
+    Face_tu(19),
+    Face_touxiao(20),
+    Face_keai(21),
+    Face_baiyan(22),
+    Face_aoman(23),
+    Face_ji_e(24),
+    Face_kun(25),
+    Face_jingkong(26),
+    Face_liuhan(27),
+    Face_hanxiao(28),
+    Face_dabing(29),
+    Face_fendou(30),
+    Face_zhouma(31),
+    Face_yiwen(32),
+    Face_yun(34),
+    Face_zhemo(35),
+    Face_shuai(36),
+    Face_kulou(37),
+    Face_qiaoda(38),
+    Face_zaijian(39),
+    Face_fadou(41),
+    Face_aiqing(42),
+    Face_tiaotiao(43),
+    Face_zhutou(46),
+    Face_yongbao(49),
+    Face_dan_gao(53),
+    Face_shandian(54),
+    Face_zhadan(55),
+    Face_dao(56),
+    Face_zuqiu(57),
+    Face_bianbian(59),
+    Face_kafei(60),
+    Face_fan(61),
+    Face_meigui(63),
+    Face_diaoxie(64),
+    Face_aixin(66),
+    Face_xinsui(67),
+    Face_liwu(69),
+    Face_taiyang(74),
+    Face_yueliang(75),
+    Face_qiang(76),
+    Face_ruo(77),
+    Face_woshou(78),
+    Face_shengli(79),
+    Face_feiwen(85),
+    Face_naohuo(86),
+    Face_xigua(89),
+    Face_lenghan(96),
+    Face_cahan(97),
+    Face_koubi(98),
+    Face_guzhang(99),
+    Face_qiudale(100),
+    Face_huaixiao(101),
+    Face_zuohengheng(102),
+    Face_youhengheng(103),
+    Face_haqian(104),
+    Face_bishi(105),
+    Face_weiqu(106),
+    Face_kuaikule(107),
+    Face_yinxian(108),
+    Face_qinqin(109),
+    Face_xia(110),
+    Face_kelian(111),
+    Face_caidao(112),
+    Face_pijiu(113),
+    Face_lanqiu(114),
+    Face_pingpang(115),
+    Face_shiai(116),
+    Face_piaochong(117),
+    Face_baoquan(118),
+    Face_gouyin(119),
+    Face_quantou(120),
+    Face_chajin(121),
+    Face_aini(122),
+    Face_bu(123),
+    Face_hao(124),
+    Face_zhuanquan(125),
+    Face_ketou(126),
+    Face_huitou(127),
+    Face_tiaosheng(128),
+    Face_huishou(129),
+    Face_jidong(130),
+    Face_jiewu(131),
+    Face_xianwen(132),
+    Face_zuotaiji(133),
+    Face_youtaiji(134),
+    Face_shuangxi(136),
+    Face_bianpao(137),
+    Face_denglong(138),
+    Face_facai(139),
+    Face_K_ge(140),
+    Face_gouwu(141),
+    Face_youjian(142),
+    Face_shuai_qi(143),
+    Face_hecai(144),
+    Face_qidao(145),
+    Face_baojin(146),
+    Face_bangbangtang(147),
+    Face_he_nai(148),
+    Face_xiamian(149),
+    Face_xiangjiao(150),
+    Face_feiji(151),
+    Face_kaiche(152),
+    Face_gaotiezuochetou(153),
+    Face_chexiang(154),
+    Face_gaotieyouchetou(155),
+    Face_duoyun(156),
+    Face_xiayu(157),
+    Face_chaopiao(158),
+    Face_xiongmao(159),
+    Face_dengpao(160),
+    Face_fengche(161),
+    Face_naozhong(162),
+    Face_dasan(163),
+    Face_caiqiu(164),
+    Face_zuanjie(165),
+    Face_shafa(166),
+    Face_zhijin(167),
+    Face_yao(168),
+    Face_shouqiang(169),
+    Face_qingwa(170),
 
+    // TODO: 2019/9/1 添加更多表情
 
     ;
 
@@ -18,4 +157,15 @@ public enum FaceID {
     public int getId() {
         return id;
     }
+
+    public static FaceID ofId(int id) {
+        for (FaceID value : FaceID.values()) {
+            if (value.id == id) {
+                return value;
+            }
+        }
+        return null;
+    }
+
+
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/message/Message.java b/mirai-core/src/main/java/net/mamoe/mirai/message/Message.java
index 16954515c..81c41ce2a 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/message/Message.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/message/Message.java
@@ -24,6 +24,10 @@ public abstract class Message {
     @Override
     public abstract String toString();
 
+    public String toDebugString() {
+        return this.getClass().getSimpleName() + String.format("(%s)", this.toString());
+    }
+
     /**
      * 把这个消息连接到另一个消息的头部. 相当于字符串相加
      * <p>
@@ -76,4 +80,5 @@ public abstract class Message {
         this.concat(new At(target));
         return this;
     }
-}
+
+}
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Face.java b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Face.java
index 3311de4e5..0f5f2cd6b 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Face.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Face.java
@@ -21,7 +21,10 @@ public final class Face extends Message {
 
     @Override
     public String toString() {
-        // TODO: 2019/9/1
-        throw new UnsupportedOperationException();
+        if (id == null) {
+            return "[face?]";
+
+        }
+        return String.format("[face%d]", id.getId());
     }
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.java b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.java
index 466a636b9..565be2fe3 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.java
@@ -11,6 +11,8 @@ import java.net.URL;
  * @author Him188moe
  */
 public final class Image extends Message {
+    private String imageID;
+
     public Image(InputStream inputStream) {
 
     }
@@ -33,11 +35,11 @@ public final class Image extends Message {
      * @param imageID
      */
     public Image(String imageID) {
-
+        this.imageID = imageID;
     }
 
     @Override
     public String toString() {
-        return null;
+        return imageID;
     }
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/MessageChain.java b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/MessageChain.java
index 9adfed317..00fb54944 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/MessageChain.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/MessageChain.java
@@ -29,6 +29,10 @@ public final class MessageChain extends Message {
         list.add(message);
     }
 
+    public MessageChain() {
+    }
+
+
     /**
      * @return An unmodifiable list
      */
@@ -45,6 +49,10 @@ public final class MessageChain extends Message {
         return this.list.stream().map(Message::toString).collect(Collectors.joining(""));
     }
 
+    public synchronized String toDebugString() {
+        return String.format("MessageChain(%s)", this.list.stream().map(Message::toDebugString).collect(Collectors.joining(", ")));
+    }
+
     @Override
     public synchronized Message concat(@NotNull Message tail) {
         this.list.add(tail);
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt
index afaf2405e..558c7351a 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt
@@ -64,6 +64,11 @@ object Protocol {
      */
     const val key0836 = "EF 4A 36 6A 16 A8 E6 3D 2E EA BD 1F 98 C1 3C DA"
 
+    /**
+     * 发送/接受消息中的一个const
+     */
+    const val friendMessageConst1 = "00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91"
+
     private val hexToByteArrayCacheMap: MutableMap<Int, ByteArray> = mutableMapOf()
 
     @ExperimentalUnsignedTypes
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
index e958d43d3..c9e3f501a 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
@@ -171,11 +171,10 @@ fun DataOutputStream.writeCRC32(key: ByteArray) {
 @ExperimentalUnsignedTypes
 @TestedSuccessfully
 fun DataOutputStream.writeDeviceName(random: Boolean = false) {
-    val deviceName: String
-    if (random) {
-        deviceName = String(getRandomByteArray(10))
+    val deviceName: String = if (random) {
+        String(getRandomByteArray(10))
     } else {
-        deviceName = InetAddress.getLocalHost().hostName
+        InetAddress.getLocalHost().hostName
     }
     this.writeShort(deviceName.length + 2)
     this.writeShort(deviceName.length)
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt
index bbaa1d796..d582503e2 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt
@@ -1,9 +1,14 @@
 package net.mamoe.mirai.network.packet
 
+import net.mamoe.mirai.message.FaceID
+import net.mamoe.mirai.message.Message
+import net.mamoe.mirai.message.defaults.Face
+import net.mamoe.mirai.message.defaults.Image
 import net.mamoe.mirai.message.defaults.MessageChain
 import net.mamoe.mirai.message.defaults.PlainText
 import net.mamoe.mirai.network.Protocol
 import net.mamoe.mirai.utils.MiraiLogger
+import net.mamoe.mirai.utils.hexToBytes
 import net.mamoe.mirai.utils.toUHexString
 import java.io.ByteArrayOutputStream
 import java.io.DataInputStream
@@ -103,15 +108,15 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
         //println(this.input.goto(110 + fontLength).readNBytesAt(2).toUHexString())//always 00 00
 
         messageType = when (val id = this.input.goto(110 + fontLength + 2).readByte().toInt()) {
-            19 -> MessageType.NORMAL
-            14 -> MessageType.XML
-            6 -> MessageType.AT
+            0x13 -> MessageType.NORMAL
+            0xE -> MessageType.XML
+            0x06 -> MessageType.AT
 
 
-            1 -> MessageType.PLAIN_TEXT
-            2 -> MessageType.FACE
-            3 -> MessageType.IMAGE
-            25 -> MessageType.ANONYMOUS
+            0x01 -> MessageType.PLAIN_TEXT
+            0x02 -> MessageType.FACE
+            0x03 -> MessageType.IMAGE
+            0x19 -> MessageType.ANONYMOUS
 
             else -> {
                 MiraiLogger debug ("ServerGroupMessageEventPacket id=$id")
@@ -185,23 +190,103 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
 
     @ExperimentalUnsignedTypes
     override fun decode() {
-        //start at Sep1.0:27
         input.goto(0)
+        println()
         println(input.readAllBytes().toUHexString())
         input.goto(0)
 
-        qq = input.readIntAt(0).toLong()
-        val msgLength = input.readShortAt(22)
-        val fontLength = input.readShortAt(93 + msgLength)
-        val offset = msgLength + fontLength
+        qq = input.readUIntAt(0).toLong()
+
+        val l1 = input.readShortAt(22)
+        input.goto(93 + l1)
+        val l2 = input.readShort()
+        input.readNBytes(l2)//font
+        input.skip(2)//2个0x00
+        message = input.readSections()
+        println(message.toDebugString())
+
+        /*
+        val offset = unknownLength0 + fontLength//57
         message = MessageChain(PlainText(let {
-            val offset2 = input.readShortAt(101 + offset)
-            input.goto(103 + offset).readVarString(offset2.toInt())
-        }))
+            val length = input.readShortAt(101 + offset)//
+            input.goto(103 + offset).readString(length.toInt())
+        }))*/
     }
 
+    private fun DataInputStream.readSection(): Message? {
+        val messageType = this.readByte().toInt()
+        val sectionLength = this.readShort().toLong()//sectionLength: short
+        this.skip(1)//message和face是 0x01, image是0x06
+        return when (messageType) {
+            0x01 -> PlainText(readShortVarString())
+            0x02 -> {
+                //00  01  AF  0B  00  08  00  01  00  04  52  CC  F5  D0  FF  00  02  14  F0
+                //00  01  0C  0B  00  08  00  01  00  04  52  CC  F5  D0  FF  00  02  14  4D
+
+                val id1 = FaceID.ofId(readShortVarNumber().toInt())//可能这个是id, 也可能下面那个
+                this.skip(this.readByte().toLong())
+                val id2 = this.readShortVarNumber()//某id?
+                return Face(id1)
+            }
+            0x06 -> {
+                this.skip(sectionLength - 37 - 1)
+                val imageId = String(this.readNBytes(36))
+                this.skip(1)//0x41
+                return Image(imageId)
+            }
+            else -> null
+        }
+
+    }
+
+    private fun DataInputStream.readSections(): MessageChain {
+        val chain = MessageChain()
+        var got: Message? = null
+        do {
+            if (got != null) {
+                chain.concat(got)
+            }
+            got = this.readSection()
+        } while (got != null)
+        return chain
+    }
 }
 
+fun main() {
+    println(String("16  20  20  39  39  31  30  20  38  38  31  43  42  20  20  20  20  20  20  31  37  36  32  65  42  39  45  32  37  32  31  43  39  36  44  37  39  41  38  32  31  36  45  30  41  44  34  30  42  35  39  35  39  31  38  36  2E  6A  70  67  66  2F  65  64  33  39  30  66  38  34  2D  34  66  38  37  2D  34  36  64  63  2D  62  33  38  35  2D  34  35  35  36  62  35  31  30  61  61  35  33  41".replace("  ", " ").hexToBytes()))
+    println(".jpg".toByteArray().size)
+}
+/*
+
+牛逼   (10404
+3E 03 3F A2 8F 00 1A E5 00 0B 53 3B 64 6B 91 17 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 40 5D 73 AF A1 01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 AF A1 1F EE 24 55 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
+
+牛逼   (10404
+3E 03 3F A2 8F 00 1A E5 00 00 86 F3 09 18 83 47 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 41 5D 73 B3 21 01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 B3 20 94 B0 82 BC 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
+
+牛逼   (19947
+76 E4 B8 DD 8F 00 1A E5 00 0D A2 8A 0A 65 7C D0 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 76 E4 B8 DD 8F 00 1A E5 4E 35 88 98 FE 64 7C E9 33 F7 2F B1 32 5D 5F A9 00 0B 77 FC 5D 73 B4 38 02 5B 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 B4 38 A6 60 C7 9A 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 0E 00 07 01 00 04 00 00 00 00
+
+牛逼   (jiahua
+B1 89 BE 09 8F 00 1A E5 00 0D EB CB 09 90 BA CF 1F 40 00 A6 00 00 00 20 00 05 00 02 00 01 00 06 00 04 00 01 05 0F 00 09 00 06 03 E9 20 02 E5 B3 00 0A 00 04 01 00 00 00 25 15 B1 89 BE 09 8F 00 1A E5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0B 77 A3 5D 73 B4 7D 00 00 5D 73 B4 7D 00 00 00 00 00 4D 53 47 00 00 00 00 00 5D 73 B4 7D 0E A3 93 E3 00 00 00 00 09 00 86 00 00 09 48 65 6C 76 65 74 69 63 61 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 0E 01 00 04 00 00 00 00 0A 00 04 00 00 00 00 19 00 1C 01 00 19 AA 02 16 08 00 88 01 00 9A 01 0E 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00
+
+牛逼   (jiahua
+B1 89 BE 09 8F 00 1A E5 00 0B 03 A2 09 90 BB 7A 1F 40 00 A6 00 00 00 20 00 05 00 02 00 01 00 06 00 04 00 01 05 0F 00 09 00 06 03 E9 20 02 E5 B3 00 0A 00 04 01 00 00 00 25 15 B1 89 BE 09 8F 00 1A E5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0B 77 A5 5D 73 B6 33 00 00 5D 73 B6 33 00 00 00 00 00 4D 53 47 00 00 00 00 00 5D 73 B6 33 22 DE A7 56 00 00 00 00 09 00 86 00 00 09 48 65 6C 76 65 74 69 63 61 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 0E 01 00 04 00 00 00 00 0A 00 04 00 00 00 00 19 00 1C 01 00 19 AA 02 16 08 00 88 01 00 9A 01 0E 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00
+
+牛逼[EMOJI表情1]牛逼   (10404
+3E 03 3F A2 8F 00 1A E5 00 0B 59 A3 64 6B 91 17 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 44 5D 73 BA D9 01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 BA D9 12 C7 FC CD 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 02 00 14 01 00 01 0C 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 4D 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
+
+牛逼[EMOJI表情2]牛逼   (10404
+3E 03 3F A2 8F 00 1A E5 00 0D 4D 4A 09 18 83 47 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 45 5D 73 BF A0 01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 BF A0 68 31 43 A2 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 02 00 14 01 00 01 AF 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 F0 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
+
+牛逼[EMOJI表情1]牛逼   (10404
+3E 03 3F A2 8F 00 1A E5 00 02 3C 8E 64 6B 91 17 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 47 5D 73 C3 76 01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 C3 75 41 3B 97 72 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 0F 01 00 0C E7 89 9B E9 80 BC E7 89 9B E9 80 BC 02 00 14 01 00 01 0C 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 4D 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
+
+[图片]  (10404
+3E 03 3F A2 8F 00 1A E5 00 0E 02 CF 64 6B A0 0C 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 4B 5D 73 D1 1C 01 1D 00 00 00 00 01 00 00 00 0C 4D 53 47 00 00 00 00 00 5D 73 D1 1C F5 78 37 16 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 06 00 F0 02 00 1B 28 5A 53 41 58 40 57 4B 52 4A 5A 31 7E 33 59 4F 53 53 4C 4D 32 4B 49 2E 6A 70 67 03 00 04 00 00 06 E2 04 00 25 2F 65 64 33 39 30 66 38 34 2D 34 66 38 37 2D 34 36 64 63 2D 62 33 38 35 2D 34 35 35 36 62 35 31 30 61 61 35 33 14 00 04 03 00 00 00 18 00 25 2F 65 64 33 39 30 66 38 34 2D 34 66 38 37 2D 34 36 64 63 2D 62 33 38 35 2D 34 35 35 36 62 35 31 30 61 61 35 33 19 00 04 00 00 00 38 1A 00 04 00 00 00 34 FF 00 63 16 20 20 39 39 31 30 20 38 38 31 43 42 20 20 20 20 20 20 31 37 36 32 65 42 39 45 32 37 32 31 43 39 36 44 37 39 41 38 32 31 36 45 30 41 44 34 30 42 35 39 35 39 31 38 36 2E 6A 70 67 66 2F 65 64 33 39 30 66 38 34 2D 34 66 38 37 2D 34 36 64 63 2D 62 33 38 35 2D 34 35 35 36 62 35 31 30 61 61 35 33 41 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
+
+ */
+
 
 /**
  * 告知服务器已经收到数据
@@ -257,7 +342,7 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
             //.gif
         }else {
             val offset2 = input.readShortAt(101 + offset)
-            input.goto(103 + offset).readVarString(offset2.toInt())
+            input.goto(103 + offset).readString(offset2.toInt())
         }
     }
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
index bb7441db4..e3051f09a 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
@@ -5,10 +5,7 @@ import net.mamoe.mirai.network.packet.PacketNameFormatter.adjustName
 import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket
 import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
 import net.mamoe.mirai.network.packet.login.*
-import net.mamoe.mirai.utils.TEA
-import net.mamoe.mirai.utils.getAllDeclaredFields
-import net.mamoe.mirai.utils.hexToBytes
-import net.mamoe.mirai.utils.toUHexString
+import net.mamoe.mirai.utils.*
 import java.io.DataInputStream
 
 /**
@@ -66,7 +63,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
                     }
 
                     return ServerLoginResponseFailedPacket(when (bytes.size) {
-                        319, 135 -> LoginState.WRONG_PASSWORD
+                        63, 319, 135, 351 -> LoginState.WRONG_PASSWORD
                         //135 -> LoginState.RETYPE_PASSWORD
                         279 -> LoginState.BLOCKED
                         263 -> LoginState.UNKNOWN_QQ_NUMBER
@@ -77,7 +74,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
                         /*
                         //unknown
                         63 -> throw IllegalArgumentException(bytes.size.toString() + " (Unknown error)")
-                        351 -> throw IllegalArgumentException(bytes.size.toString() + " (Illegal package data or Unknown error)")//包数据有误
+                        351 -> throw IllegalArgumentException(bytes.size.toString() + " (Unknown error)")
 
                         else -> throw IllegalArgumentException(bytes.size.toString())*/
                     }, stream).apply { this.idHex = idHex }
@@ -183,7 +180,7 @@ fun DataInputStream.readShortVarString(): String {
     return String(this.readNBytes(this.readShort().toInt()))
 }
 
-fun DataInputStream.readVarString(length: Int): String {
+fun DataInputStream.readString(length: Int): String {
     return String(this.readNBytes(length))
 }
 
@@ -208,6 +205,17 @@ fun <N : Number> DataInputStream.readNBytes(length: N): ByteArray {
     return this.readNBytes(length.toInt())
 }
 
+
+fun DataInputStream.readShortVarNumber(): Number {
+    return when (this.readShort().toInt()) {
+        1 -> this.readByte()
+        2 -> this.readShort()
+        4 -> this.readInt()
+        8 -> this.readLong()
+        else -> throw UnsupportedOperationException()
+    }
+}
+
 fun DataInputStream.readNBytesIn(range: IntRange): ByteArray {
     this.goto(range.first)
     return this.readNBytes(range.last - range.first + 1)
@@ -218,6 +226,12 @@ fun <N : Number> DataInputStream.readIntAt(position: N): Int {
     return this.readInt();
 }
 
+@ExperimentalUnsignedTypes
+fun <N : Number> DataInputStream.readUIntAt(position: N): UInt {
+    this.goto(position)
+    return this.readNBytes(4).toUInt();
+}
+
 fun <N : Number> DataInputStream.readByteAt(position: N): Byte {
     this.goto(position)
     return this.readByte();
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendFriendMessagePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendFriendMessagePacket.kt
index 0bea83586..768993e77 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendFriendMessagePacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendFriendMessagePacket.kt
@@ -35,7 +35,8 @@ class ClientSendFriendMessagePacket(
             it.writeHex("00 00 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00")
             it.writeTime()
             it.writeRandom(4)
-            it.writeHex("00 00 00 00 09 00 86 00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91")
+            it.writeHex("00 00 00 00 09 00 86")
+            it.writeHex(Protocol.friendMessageConst1)
             it.writeZero(2)
 
             if ("[face" in message
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendGroupMessagePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendGroupMessagePacket.kt
index 4abd29fed..b26a24316 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendGroupMessagePacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendGroupMessagePacket.kt
@@ -30,7 +30,7 @@ class ClientSendGroupMessagePacket(
             it.writeHex("00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00")
             it.writeTime()
             it.writeRandom(4)
-            it.writeHex("00 00 00 00 09 00 86 00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91")
+            it.writeHex("Protocol.messageConst1")
             it.writeZero(2)
 
             //messages
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt
index 02ed9bdae..b83597ad1 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt
@@ -101,7 +101,7 @@ private fun DataOutputStream.writePart1(qq: Long, password: String, loginTime: I
     this.writeHex("00 38")//length
     this.write(token0825)//length
     this.writeHex("03 0F")//tag
-    this.writeDeviceName(true)//todo 随机
+    this.writeDeviceName(false)
 
     this.writeHex("00 05 00 06 00 02")
     this.writeQQ(qq)
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt
index 9b71375d6..438b1259d 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt
@@ -4,7 +4,7 @@ import net.mamoe.mirai.network.Protocol
 import net.mamoe.mirai.network.packet.ServerPacket
 import net.mamoe.mirai.network.packet.goto
 import net.mamoe.mirai.network.packet.readNBytesAt
-import net.mamoe.mirai.network.packet.readVarString
+import net.mamoe.mirai.network.packet.readString
 import net.mamoe.mirai.utils.TestedSuccessfully
 import net.mamoe.mirai.utils.toUHexString
 import java.io.DataInputStream
@@ -43,7 +43,7 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in
         this.token88 = this.input.readNBytesAt(189 + msgLength, 136)
 
         val nickLength = this.input.goto(624 + msgLength).readByte().toInt()
-        this.nickname = this.input.readVarString(nickLength)
+        this.nickname = this.input.readString(nickLength)
 
         //this.age = this.input.goto(packetDataLength - 28).readShortAt()
 
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt b/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
index 6b805a8a3..39c3bb1d8 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
@@ -55,10 +55,11 @@ fun String.hexToBytes(): ByteArray = Protocol.hexToBytes(this)
 fun String.hexToUBytes(): UByteArray = Protocol.hexToUBytes(this)
 
 @ExperimentalUnsignedTypes
-fun String.hexToShort(): Short = hexToBytes().let { ((it[1].toInt() shl 8) + it[0]).toShort() }
+fun String.hexToInt(): Int = hexToBytes().toUInt().toInt()
 
 @ExperimentalUnsignedTypes
-fun String.hexToInt(): Int = hexToBytes().let { ((it[0].toInt() shl 24) + (it[1].toInt() shl 16) + (it[2].toInt() shl 8) + it[3]) }
+fun ByteArray.toUInt(): UInt =
+        this[0].toUInt().and(255u).shl(24) + this[1].toUInt().and(255u).shl(16) + this[2].toUInt().and(255u).shl(8) + this[3].toUInt().and(255u).shl(0)
 
 open class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream()) {
     open fun toByteArray(): ByteArray = (out as ByteArrayOutputStream).toByteArray()
diff --git a/mirai-core/src/test/java/HexComparator.java b/mirai-core/src/test/java/HexComparator.java
index 6cadeb451..66d73c2b5 100644
--- a/mirai-core/src/test/java/HexComparator.java
+++ b/mirai-core/src/test/java/HexComparator.java
@@ -50,10 +50,20 @@ public class HexComparator {
 
         @SuppressWarnings({"unused", "NonAsciiCharacters"})
         private static class TestConsts {
-            private static final String 牛逼 = UtilsKt.toUHexString("牛逼".getBytes(), " ");
+            private static final String NIU_BI = UtilsKt.toUHexString("牛逼".getBytes(), " ");
             private static final String _1994701021 = ClientPacketKt.toUHexString(1994701021, " ");
             private static final String _1040400290 = ClientPacketKt.toUHexString(1040400290, " ");
             private static final String _580266363 = ClientPacketKt.toUHexString(580266363, " ");
+
+            private static final String _1040400290_ = "3E 03 3F A2";
+            private static final String _1994701021_ = "76 E4 B8 DD";
+            private static final String _jiahua_ = "B1 89 BE 09";
+
+            private static final String SINGLE_PLAIN_MESSAGE_HEAD = "00 00 01 00 09 01";
+
+            private static final String MESSAGE_TAIL_10404 = "0E  00  07  01  00  04  00  00  00  09 19  00  18  01  00  15  AA  02  12  9A  01  0F  80  01  01  C8  01  00  F0  01  00  F8  01  00  90  02  00".replace("  ", " ");
+            //private static final String MESSAGE_TAIL2_10404 ="".replace("  ", " ");
+
         }
 
         private final List<Match> matches = new LinkedList<>();
@@ -88,7 +98,7 @@ public class HexComparator {
                 return new LinkedList<>();
             }
             return new LinkedList<>() {{
-                int index = 0;
+                int index = -1;
                 while ((index = hex.indexOf(constValue, index + 1)) != -1) {
                     add(new IntRange(index / 3, (index + constValue.length()) / 3));
                 }
@@ -105,18 +115,20 @@ public class HexComparator {
     }
 
     private static void buildConstNameChain(int length, ConstMatcher constMatcher, StringBuilder constNameBuilder) {
+        //System.out.println(constMatcher.matches);
         for (int i = 0; i < length; i++) {
             constNameBuilder.append(" ");
             String match = constMatcher.getMatchedConstName(i / 4);
             if (match != null) {
                 int appendedNameLength = match.length();
                 constNameBuilder.append(match);
-                while (constMatcher.getMatchedConstName(i++ / 4) != null) {
-                    if (appendedNameLength-- <= 0) {
+                while (match.equals(constMatcher.getMatchedConstName(i++ / 4))) {
+                    if (appendedNameLength-- < 0) {
                         constNameBuilder.append(" ");
                     }
                 }
 
+                constNameBuilder.append(" ".repeat(match.length() % 4));
             }
         }
     }
@@ -281,10 +293,10 @@ public class HexComparator {
         System.out.println(HexComparator.compare(
                 //mirai
 
-                "2A 22 96 29 7B 00 40 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 EC 21 40 06 18 89 54 BC 00 00 00 00 09 00 86 00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 0A 01 00 07 E7 89 9B E9 80 BC 21\n"
+                "2A 22 96 29 7B 00 40 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 EC 21 40 06 18 89 54 BC Protocol.messageConst1 00 00 01 00 0A 01 00 07 E7 89 9B E9 80 BC 21\n"
                 ,
                 //e
-                "2A 22 96 29 7B 00 3F 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 5D 6B 8E 1A FE 39 0B FC 00 00 00 00 09 00 86 00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 0A 01 00 07 6D 65 73 73 61 67 65"
+                "2A 22 96 29 7B 00 3F 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 5D 6B 8E 1A FE 39 0B FC Protocol.messageConst1 00 00 01 00 0A 01 00 07 6D 65 73 73 61 67 65"
         ));