diff --git a/mirai-core/src/main/java/net/mamoe/mirai/Robot.java b/mirai-core/src/main/java/net/mamoe/mirai/Robot.java
index 459ef78bb..16469e5d2 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/Robot.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/Robot.java
@@ -1,8 +1,6 @@
 package net.mamoe.mirai;
 
 import lombok.Getter;
-import net.mamoe.mirai.contact.Contact;
-import net.mamoe.mirai.message.Message;
 import net.mamoe.mirai.network.RobotNetworkHandler;
 import net.mamoe.mirai.utils.config.MiraiConfigSection;
 
@@ -42,7 +40,7 @@ public class Robot {
         this.qq = qq;
         this.password = password;
         this.owners = Collections.unmodifiableList(owners);
-        this.handler = new RobotNetworkHandler(this.qq, this.password);
+        this.handler = new RobotNetworkHandler(this, this.qq, this.password);
     }
 
 
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventManager.java b/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventManager.java
index 50051df38..ee01f3a4b 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventManager.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventManager.java
@@ -4,7 +4,6 @@ import net.mamoe.mirai.MiraiServer;
 import net.mamoe.mirai.event.events.MiraiEvent;
 
 import java.util.*;
-import java.util.concurrent.Callable;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.Consumer;
@@ -108,11 +107,12 @@ public class MiraiEventManager {
     }
 
 
-    public void ansycBroadcastEvent(MiraiEvent event){
-        this.ansycBroadcastEvent(event,a -> {});
+    public void asyncBroadcastEvent(MiraiEvent event) {
+        this.asyncBroadcastEvent(event, a -> {
+        });
     }
 
-    public <D extends MiraiEvent> void ansycBroadcastEvent(D event, Consumer<D> callback){
+    public <D extends MiraiEvent> void asyncBroadcastEvent(D event, Consumer<D> callback) {
         MiraiServer.getInstance().getTaskManager().ansycTask(() -> {
             MiraiEventManager.this.broadcastEvent(event);
             return event;
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotConnectedEvent.java b/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotConnectedEvent.java
deleted file mode 100644
index 02c578a7b..000000000
--- a/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotConnectedEvent.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package net.mamoe.mirai.event.events.robot;
-
-import net.mamoe.mirai.Robot;
-
-public class RobotConnectedEvent extends RobotEvent {
-
-    public RobotConnectedEvent(Robot robot) {
-        super(robot);
-    }
-
-}
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotEvent.java b/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotEvent.java
index e98e743b4..5c1ad7b68 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotEvent.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotEvent.java
@@ -1,13 +1,15 @@
 package net.mamoe.mirai.event.events.robot;
 
-import lombok.Getter;
 import net.mamoe.mirai.Robot;
 import net.mamoe.mirai.event.events.MiraiEvent;
 
 public abstract class RobotEvent extends MiraiEvent {
-    @Getter
     private final Robot robot;
 
+    public Robot getRobot() {
+        return robot;
+    }
+
     public RobotEvent(Robot robot){
         this.robot = robot;
     }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotLoginSucceedEvent.java b/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotLoginSucceedEvent.java
new file mode 100644
index 000000000..15151ea91
--- /dev/null
+++ b/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotLoginSucceedEvent.java
@@ -0,0 +1,11 @@
+package net.mamoe.mirai.event.events.robot;
+
+import net.mamoe.mirai.Robot;
+
+public final class RobotLoginSucceedEvent extends RobotEvent {
+
+    public RobotLoginSucceedEvent(Robot robot) {
+        super(robot);
+    }
+
+}
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
index 2f41251b6..1fc5b887f 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
@@ -1,6 +1,9 @@
 package net.mamoe.mirai.network
 
 import net.mamoe.mirai.MiraiServer
+import net.mamoe.mirai.Robot
+import net.mamoe.mirai.event.MiraiEventManager
+import net.mamoe.mirai.event.events.robot.RobotLoginSucceedEvent
 import net.mamoe.mirai.network.packet.*
 import net.mamoe.mirai.network.packet.login.*
 import net.mamoe.mirai.network.packet.verification.ServerVerificationCodePacket
@@ -22,7 +25,7 @@ import java.util.concurrent.TimeUnit
  * @author Him188moe
  */
 @ExperimentalUnsignedTypes
-class RobotNetworkHandler(val number: Int, private val password: String) {
+class RobotNetworkHandler(val robot: Robot, val number: Int, private val password: String) {
 
     private var sequence: Int = 0
 
@@ -193,6 +196,7 @@ class RobotNetworkHandler(val number: Int, private val password: String) {
                 MiraiThreadPool.getInstance().scheduleWithFixedDelay({
                     sendPacket(ClientHeartbeatPacket(this.number, this.sessionKey))
                 }, 90000, 90000, TimeUnit.MILLISECONDS)
+                MiraiEventManager.getInstance().asyncBroadcastEvent(RobotLoginSucceedEvent(robot))
                 this.tlv0105 = packet.tlv0105
                 sendPacket(ClientLoginStatusPacket(this.number, this.sessionKey, ClientLoginStatus.ONLINE))
             }
@@ -240,6 +244,10 @@ class RobotNetworkHandler(val number: Int, private val password: String) {
 
             }
 
+            is ServerGroupUploadFileEventPacket -> {
+
+            }
+
             is ServerVerificationCodePacketEncrypted -> onPacketReceived(packet.decrypt(this.token00BA))
             is ServerLoginResponseVerificationCodePacketEncrypted -> onPacketReceived(packet.decrypt())
             is ServerLoginResponseResendPacketEncrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!))
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 012279ec4..d341b4bda 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,6 +1,5 @@
 package net.mamoe.mirai.network.packet
 
-import net.mamoe.mirai.util.toUHexString
 import net.mamoe.mirai.utils.MiraiLogger
 import java.io.ByteArrayOutputStream
 import java.io.DataInputStream
@@ -33,7 +32,7 @@ class ServerGroupUploadFileEventPacket(input: DataInputStream, packetId: ByteArr
     lateinit var message: String
 
     override fun decode() {
-        message = String(this.input.goto(64).readNBytes(this.input.goto(60).readShort().toInt()))
+        message = String(this.input.goto(65).readNBytes(this.input.goto(60).readShort().toInt()))
     }//todo test
 }
 
@@ -47,7 +46,12 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
         NORMAL,
         XML,
         AT,
-        IMAGE,
+        FACE,//qq自带表情 [face107.gif]
+
+        PLAIN_TEXT, //纯文本
+        IMAGE, //自定义图片 {F50C5235-F958-6DF7-4EFA-397736E125A4}.gif
+
+        ANONYMOUS,//匿名用户发出的消息
 
         OTHER,
     }
@@ -56,17 +60,26 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
         group = this.input.goto(51).readInt()
         qq = this.input.goto(56).readInt()
         val fontLength = this.input.goto(108).readShort()
-        println(this.input.goto(110 + fontLength).readNBytes(2).toUHexString())
+        //println(this.input.goto(110 + fontLength).readNBytes(2).toUHexString())//always 00 00
 
         messageType = when (val id = this.input.goto(110 + fontLength + 2).readByte().toInt()) {
             19 -> MessageType.NORMAL
             14 -> MessageType.XML
-            2 -> MessageType.IMAGE
             6 -> MessageType.AT
 
-            else -> MessageType.OTHER
+
+            1 -> MessageType.PLAIN_TEXT
+            2 -> MessageType.FACE
+            3 -> MessageType.IMAGE
+            25 -> MessageType.ANONYMOUS
+
+            else -> {
+                println("id=$id")
+                MessageType.OTHER
+            }
         }
 
+
         when (messageType) {
             MessageType.NORMAL -> {
                 val gzippedMessage = this.input.goto(110 + fontLength + 16).readNBytes(this.input.goto(110 + fontLength + 3).readShort().toInt() - 11)
@@ -84,7 +97,7 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
                 }
             }
 
-            MessageType.IMAGE -> {
+            MessageType.FACE -> {
                 val faceId = this.input.goto(110 + fontLength + 8).readByte()
                 message = "[face${faceId}.gif]"
             }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/message/ClientFriendMessagePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/message/ClientFriendMessagePacket.kt
new file mode 100644
index 000000000..568abc8d4
--- /dev/null
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/message/ClientFriendMessagePacket.kt
@@ -0,0 +1,17 @@
+package net.mamoe.mirai.network.packet.message
+
+import net.mamoe.mirai.network.packet.ClientPacket
+
+/**
+ * @author Him188moe
+ */
+@ExperimentalUnsignedTypes
+class ClientFriendMessagePacket(
+        val qq: Int,
+        val sessionKey: ByteArray,
+        val message: String
+) : ClientPacket() {
+    override fun encode() {
+
+    }
+}
\ No newline at end of file