public void OnReceiveCallback(IAsyncResult IAR)
        {
            try
            {
                receiveDone.Reset();
                Socket recvSock = (Socket)IAR.AsyncState;
                int receiveLen = recvSock.EndReceive(IAR);
                byte[] receiveBuffer = this.sockBuffer;
                receiveDone.Set();

                if (receiveLen > 0)
                {
                    if (receiveBuffer[0] == 0xFF)
                    {
                        int bnetResult;
                        BnetPacketStruct bnetPackSt = bnetProtocol.decapsulize(receiveBuffer);
                        switch (bnetPackSt.packet_id)
                        {
                            case BnetPacketModel.SID_OPTIONALWORK:
                            case BnetPacketModel.SID_EXTRAWORK:
                            case BnetPacketModel.SID_REQUIREDWORK:
                                this.getHandleMsg("미사용 패킷: " + bnetPackSt.packet_id.ToString("X"));
                                break;
                            case BnetPacketModel.SID_NULL:
                                bnetProtocol.send(recvSock, BnetPacketModel.SID_NULL);
                                break;
                            case BnetPacketModel.SID_PING:
                                bnetProtocol.setBnetByte(bnetPackSt.pack_data.ToArray());
                                bnetProtocol.send(recvSock, BnetPacketModel.SID_PING);
                                this.getHandleMsg(BnetCode.ConnectionPING);
                                break;
                            case BnetPacketModel.SID_AUTH_INFO:
                                bnetProtocol.nlsRevision = bnetPacketStream.readDword(bnetPackSt.pack_data.ToArray(), 0);
                                bnetProtocol.serverToken = bnetPacketStream.readDword(bnetPackSt.pack_data.ToArray(), 4);

                                bnetProtocol.setBnetByte(bnetProtocol.clientToken);
                                bnetProtocol.setBnetByte(0x00000000); // EXE Version
                                bnetProtocol.setBnetByte(0x00000000); // EXE Hash
                                bnetProtocol.setBnetByte(0x00000001); // Number of CD-Key
                                bnetProtocol.setBnetByte(0x00000000); // Spawn CD-Key
                                bnetProtocol.setBnetByte(0x00000000);
                                bnetProtocol.setBnetByte(0x00000000);
                                bnetProtocol.setBnetByte(0x00000000);
                                bnetProtocol.setBnetByte(0x00000000);
                                bnetProtocol.setBnetByte(0x00000000);
                                bnetProtocol.setBnetByte(0x00000000);
                                bnetProtocol.setBnetByte(0x00000000);
                                bnetProtocol.setBnetByte(0x00000000);
                                bnetProtocol.setBnetByte(0x00000000);
                                bnetProtocol.setBnetByte("war3.exe 03/18/11 20:03:55 471040", true);
                                bnetProtocol.setBnetByte("Chat", true);
                                bnetProtocol.send(recvSock, BnetPacketModel.SID_AUTH_CHECK);
                                this.getHandleMsg(BnetCode.ConnectionAUTH_INFO);
                                break;
                            case BnetPacketModel.SID_AUTH_CHECK:
                                bnetResult = BitConverter.ToInt32(bnetPackSt.pack_data.ToArray(), 0);
                                if (bnetResult != 0)
                                {
                                    switch (bnetResult)
                                    {
                                        case 0x201:
                                            this.getHandleMsg(BnetCode.ServerBen);
                                            break;
                                        default:
                                            this.getHandleMsg(BnetCode.UnkownError);
                                            break;
                                    }
                                }
                                else
                                {
                                    byte[] bnetPwHash = bnetProtocol.encriptDobuleHash(bnetUserPw);

                                    bnetProtocol.setBnetByte(bnetProtocol.clientToken);
                                    bnetProtocol.setBnetByte(bnetProtocol.serverToken);
                                    bnetProtocol.setBnetByte(BitConverter.ToUInt32(bnetPwHash, 0));
                                    bnetProtocol.setBnetByte(BitConverter.ToUInt32(bnetPwHash, 4));
                                    bnetProtocol.setBnetByte(BitConverter.ToUInt32(bnetPwHash, 8));
                                    bnetProtocol.setBnetByte(BitConverter.ToUInt32(bnetPwHash, 12));
                                    bnetProtocol.setBnetByte(BitConverter.ToUInt32(bnetPwHash, 16));
                                    bnetProtocol.setBnetByte(bnetUsrId, true);
                                    bnetProtocol.send(recvSock, BnetPacketModel.SID_LOGONRESPONSE2);
                                    this.getHandleMsg(BnetCode.ConnectionAUTH_CHECK);
                                }
                                break;
                            case BnetPacketModel.SID_LOGONRESPONSE2:
                                bnetResult = BitConverter.ToInt32(bnetPackSt.pack_data.ToArray(), 0);
                                switch (bnetResult)
                                {
                                    case 0x00:
                                        this.getHandleMsg(BnetCode.LOGONRESP_Success);
                                        bnetProtocol.setBnetByte(0x00);
                                        bnetProtocol.setBnetByte(0x00);
                                        bnetProtocol.send(recvSock, BnetPacketModel.SID_ENTERCHAT);
                                        break;
                                    case 0x01:
                                        this.getHandleMsg(BnetCode.LOGONRESP_FaildID);
                                        OnChatUserLoginFaild(BnetCode.LOGONRESP_FaildID);
                                        break;
                                    case 0x02:
                                        this.getHandleMsg(BnetCode.LOGONRESP_FaildPW);
                                        OnChatUserLoginFaild(BnetCode.LOGONRESP_FaildPW);
                                        break;
                                    case 0x06:
                                        this.getHandleMsg(BnetCode.LOGONRESP_LockedID);
                                        OnChatUserLoginFaild(BnetCode.LOGONRESP_LockedID);
                                        break;
                                    default:
                                        this.getHandleMsg(BnetCode.UnkownError);
                                        OnChatUserLoginFaild(BnetCode.UnkownError);
                                        break;
                                }
                                break;
                            case BnetPacketModel.SID_ENTERCHAT:
                                this.getHandleMsg(BnetCode.ENTERCHAT);
                                this.getHandleMsg(Encoding.UTF8.GetString(bnetPackSt.pack_data.ToArray()));
                                this.bnetUserUid = bnetPackSt.getUsername(bnetPackSt.getData(bnetPackSt.pack_data.ToArray()));
                                OnChatLogined(this.bnetUserUid);
                                bnetProtocol.setBnetByte(0x01);
                                bnetProtocol.setBnetByte(firstJoinChannel, true);
                                bnetProtocol.send(recvSock, BnetPacketModel.SID_JOINCHANNEL);
                                this.commandFriendsUpdate(this.bnetSock);
                                //Thread musicBotThread = new Thread(new ThreadStart(MusicBot));
                                //musicBotThread.Start();
                                break;
                            case BnetPacketModel.SID_CHATEVENT:
                                BnetPacketEvent bnetPacketEvent = (BnetPacketEvent)BitConverter.ToUInt32(bnetPackSt.pack_data.ToArray(), 0);
                                uint flags = BitConverter.ToUInt32(bnetPackSt.pack_data.ToArray(), 4);
                                uint ping = BitConverter.ToUInt32(bnetPackSt.pack_data.ToArray(), 8);
                                String message;
                                BnetUsername user = bnetPackSt.getUsername(bnetPackSt.getData(bnetPackSt.pack_data.ToArray(), 24));

                                switch (bnetPacketEvent)
                                {
                                    case BnetPacketEvent.EID_CHANNEL:
                                        String channel = bnetPackSt.getData(bnetPackSt.pack_data.ToArray());
                                        this.getHandleMsg("채널 유저 확인:" + user.name);
                                        bnetCurrentChannel = channel;
                                        OnChatInfo(this.bnetUserUid, "님이 " + channel + " 채널에 입장.");
                                        bnetUserList = new List<BnetUsername>();
                                        bnetUserList.Add(this.bnetUserUid);
                                        OnChatUserUpdate(bnetUserList.ToArray());
                                        OnChatUserChannelMove(this.bnetUserUid, channel);
                                        break;
                                    case BnetPacketEvent.EID_USERFLAGS:
                                        this.getHandleMsg("플래그 유저 확인:" + user.name);
                                        bnetUserList = bnetPacketStream.getUserFlags(bnetPackSt, receiveBuffer);
                                        bnetUserList = bnetUserList.Distinct().ToList();
                                        OnChatUserUpdate(bnetUserList.ToArray());

                                        foreach(var data in bnetUserList)
                                        {
                                            this.getHandleMsg("플래그 서브 유저:" + data.name);
                                        }
                                        break;
                                    case BnetPacketEvent.EID_SHOWUSER:
                                        this.getHandleMsg("SHOW 유저 확인:" + user.name);
                                        break;
                                    case BnetPacketEvent.EID_ERROR:
                                        message = bnetPackSt.getData(bnetPackSt.pack_data.ToArray());
                                        this.getHandleMsg(message);
                                        OnChatError(user, message);
                                        break;
                                    case BnetPacketEvent.EID_INFO:
                                    case BnetPacketEvent.EID_BROADCAST:
                                        message = bnetPackSt.getData(bnetPackSt.pack_data.ToArray());
                                        this.getHandleMsg(message);
                                        OnChatInfo(user, message);
                                        break;
                                    case BnetPacketEvent.EID_WHISPER:
                                    case BnetPacketEvent.EID_WHISPERSENT:
                                        message = bnetPackSt.getData(bnetPackSt.pack_data.ToArray());
                                        this.getHandleMsg(message);
                                        OnChatWhisper(user, message);
                                        break;
                                    case BnetPacketEvent.EID_TALK:
                                        message = bnetPackSt.getData(bnetPackSt.pack_data.ToArray());
                                        this.getHandleMsg(message);
                                        OnChatUser(user, message);
                                        break;
                                    case BnetPacketEvent.EID_JOIN:
                                        message = bnetPackSt.getData(bnetPackSt.pack_data.ToArray());
                                        this.getHandleMsg("Join: " + user + " : " + message);
                                        OnChatJoin(user);
                                        bnetUserList.Add(user);
                                        bnetUserList = bnetUserList.Distinct().ToList();
                                        OnChatUserUpdate(bnetUserList.ToArray());
                                        break;
                                    case BnetPacketEvent.EID_LEAVE:
                                        message = bnetPackSt.getData(bnetPackSt.pack_data.ToArray());
                                        this.getHandleMsg("Leave: " + user + " : " + message);
                                        OnChatLeave(user);
                                        bnetUserList.RemoveAll(x => x.name == user.name);
                                        OnChatUserUpdate(bnetUserList.ToArray());
                                        break;
                                    default:
                                        this.getHandleMsg("별도 타입 패킷 [EID]: " + bnetPacketEvent.ToString("X"));
                                        break;
                                }
                                break;
                            case BnetPacketModel.SID_FRIENDSLIST:
                                uint seek = 0;
                                byte cnt = bnetPackSt.pack_data[(int)seek++];
                                BnetFriends[] bnetFriends = new BnetFriends[(int)cnt];
                                this.getHandleMsg(BnetCode.Search_FriendList);
                                this.getHandleMsg("탐색 된 프랜즈 " + cnt.ToString() + " 명");
                                int player;
                                for (player = 0; player < cnt; player++)
                                {
                                    bnetFriends[player].name = bnetPackSt.getUsername(bnetPackSt.getData(bnetPackSt.pack_data.ToArray()));
                                    seek = bnetPackSt.getSeek();
                                    bnetFriends[player].status = bnetPackSt.pack_data[(int)seek++];
                                    bnetFriends[player].location = bnetPackSt.pack_data[(int)seek++];
                                    bnetFriends[player].product = BitConverter.ToUInt32(bnetPackSt.pack_data.ToArray(), (int)seek);
                                    bnetFriends[player].locationName = bnetPackSt.getData(bnetPackSt.pack_data.ToArray(), seek + 4);
                                }

                                try
                                {
                                    OnChatFriendsUpdate(bnetFriends);
                                }
                                catch (NullReferenceException e)
                                {
                                    this.getHandleMsg(e.StackTrace);
                                }
                                break;
                            default:
                                this.getHandleMsg("별도 타입 패킷: " + bnetPackSt.packet_id.ToString("X"));
                                break;
                        }
                    }
                    this.BindREceiveHandler(recvSock);
                }
                else
                {
                    recvSock.Close();
                }
            }
            catch (SocketException e)
            {
                this.getHandleMsg(e.StackTrace);
            }
        }
 private void OnChatFriendsUpdateHandler(BnetFriends[] bnetFriends)
 {
     Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate {
         FriendsList.Items.Clear();
         BnetChattingColor bnetChattingColor = new BnetChattingColor();
         for (int i=0; i<bnetFriends.Length; i++)
         {
             if(bnetFriends[i].name.name == bnetUsername.name)
             {
                 bnetChattingColor = BnetChattingColor.Me;
             } else
             {
                 bnetChattingColor = BnetChattingColor.Plain;
             }
             this.AddListFriend(bnetFriends[i].name, bnetFriends[i].locationName, bnetChattingColor);
         }
     }));
 }