private void ParseBnls(byte[] incomingData, IBnlsRequestToken node)
        {
            DataReader dr = new DataReader(incomingData);

            dr.ReadInt16();
            byte pktId = dr.ReadByte();

            switch (pktId)
            {
                case 0x01:
                    VersionCheckRequestToken vcrt2 = node as VersionCheckRequestToken;

                    dr.ReadInt32();
                    int cdKeySeed = dr.ReadInt32();
                    vcrt2.ClientToken = cdKeySeed;
                   
                    int[] cdKeyData = dr.ReadInt32Array(9);

                    vcrt2.CdKeySeed = cdKeySeed;
                    vcrt2.CdKeyData = cdKeyData;

                    Messenger.Default.Send<IBnlsRequestToken>(node, node);

                    vcrt2.RequestBuffer = null;
                    vcrt2.RequestBufferCount = 0;
                    break;

                case 0x02:
                    LogonChallengeRequestToken lcrt = node as LogonChallengeRequestToken;

                    int[] challengeData = dr.ReadInt32Array(8);

                    lcrt.ChallengeData = challengeData;
                    Messenger.Default.Send<IBnlsRequestToken>(node, node);

                    lcrt.RequestBuffer = null;
                    lcrt.RequestBufferCount = 0;

                    break;

                case 0x03:
                    LogonProofRequestToken lprt = node as LogonProofRequestToken;

                    int[] logonProofData = dr.ReadInt32Array(5);
                    lprt.LogonProofData = logonProofData;

                    Messenger.Default.Send<IBnlsRequestToken>(node, node);

                    lprt.RequestBuffer = null;
                    lprt.RequestBufferCount = 0;

                    break;

                case 0x04:
                    CreateAccountRequestToken cart = node as CreateAccountRequestToken;

                    int[] accountCreateData = dr.ReadInt32Array(16);
                    cart.AccountCreateData = accountCreateData;

                    Messenger.Default.Send<IBnlsRequestToken>(node, node);

                    cart.RequestBuffer = null;
                    cart.RequestBufferCount = 0;

                    break;

                case 0x0D:
                    node.RequestBuffer = null;
                    node.RequestBufferCount = 0;

                    break;
                
                case 0x1A:
                    dr.ReadInt32();
                    VersionCheckRequestToken vcrt = node as VersionCheckRequestToken;

                    vcrt.Version = dr.ReadInt32();
                    vcrt.Checksum = dr.ReadInt32();
                    vcrt.Statstring = dr.ReadByteArrayNt();

                    dr.ReadInt32();

                    vcrt.VersionByte = dr.ReadInt32();

                    Messenger.Default.Send<IBnlsRequestToken>(node, node);

                    vcrt.RequestBufferCount = 0;
                    vcrt.RequestBuffer = null;

                    break;
            }
        }
        private void ParseBnet(byte[] incomingData)
        {
            DataReader dr = new DataReader(incomingData);
            BnetEvent cachedBeObj = new BnetEvent();

            dr.ReadByte();
            byte pktId = dr.ReadByte();
            dr.ReadInt16();

            switch (pktId)
            {
                case 0x00:
                    BnetPacket nullPkt = new BnetPacket();
                    SendPacket(0x00, nullPkt);

                    break;
                case 0x25:
                    BnetPacket pingPkt = new BnetPacket();
                    pingPkt.InsertInt32(dr.ReadInt32());

                    SendPacket(0x25, pingPkt);

                    break;
                case 0x26:
                    dr.ReadInt32(); // Account number
                    dr.ReadInt32(); // Key number
                    dr.ReadInt32(); // Request Id;

                    string location = dr.ReadString();
                    string description = dr.ReadString();

                    LegacyProfileRequest lpr = new LegacyProfileRequest();
                    lpr.Location = location;
                    lpr.Description = description;

                    Messenger.Default.Send<ProfileRequest>(lpr, connectionToken);

                    break;
                case 0x35:
                    dr.ReadInt32();
                    byte success = dr.ReadByte();

                    string w3Desc = dr.ReadString();
                    string w3Loc = dr.ReadString();

                    int clanTag = dr.ReadInt32();

                    if (cachedW3ProfileRequest == null)
                        cachedW3ProfileRequest = new War3ProfileRequest();

                    cachedW3ProfileRequest.Location = w3Loc;
                    cachedW3ProfileRequest.Description = w3Desc;

                    if (clanTag != 0)
                    {
                        // Request SID_CLANMEMBERINFORMATION
                        BnetPacket clanMemInfoPkt = new BnetPacket();
                        clanMemInfoPkt.InsertInt32(0);
                        clanMemInfoPkt.InsertInt32(clanTag);
                        clanMemInfoPkt.InsertString(cachedW3RequestName);

                //        SendPacket(0x82, clanMemInfoPkt);   

                        BnetPacket clanStatPkt = new BnetPacket();
                        clanStatPkt.InsertByte(0x08);
                        clanStatPkt.InsertInt32(0);
                        clanStatPkt.InsertInt32(clanTag);
                        clanStatPkt.InsertBytes(System.Text.Encoding.UTF8.GetBytes("3RAW"));

                        //SendPacket(0x44, clanStatPkt);
                    }

                    break;
         
                case 0x44:
                    break;
                case 0x82:
                    dr.ReadInt32();
                    dr.ReadByte();
                    System.Diagnostics.Debug.WriteLine("Clan Name {0}", dr.ReadString());
                    break;
                case 0x3D:
                    // Account creation
                    int legacyCreationResult = dr.ReadInt32();
                    switch (legacyCreationResult)
                    {
                        case 0x00:
                            BnetPacket logonResponse2 = new BnetPacket();
                             
                            logonResponse2.InsertInt32(clientToken);
                            logonResponse2.InsertInt32(serverToken);
                            logonResponse2.InsertBytes(MBNCSUtil.OldAuth.DoubleHashPassword(botAccount.Password.ToLower(), clientToken, serverToken));
                            logonResponse2.InsertString(botAccount.Username);

                            SendPacket(0x3A, logonResponse2); // SID_LOGONRESPONSE2

                            break;
                    }

                    break;
                case 0x50:
                    dr.ReadInt32(); // Logon Type
                    serverToken = dr.ReadInt32();
                    clientToken = Environment.TickCount;
                    dr.ReadInt32(); // UDPValue
                    long fileTime = dr.ReadInt64();
                    string versionName = dr.ReadString();
                    byte[] checksumForm = dr.ReadByteArrayNt();

                    var versionCheckRequestToken = new VersionCheckRequestToken((int)botAccount.Product, fileTime, versionName, checksumForm, serverToken, botAccount.CdKey);
                    Messenger.Default.Register<IBnlsRequestToken>(this, versionCheckRequestToken, true, ReceivedBnlsMessage);

                   BnlsService.Instance.BnlsVersionCheckRequest(versionCheckRequestToken);
               
                    break;
                case 0x51:
                    int result = dr.ReadInt32();
                    
                    switch(result)
                    {
                        case 0x000:
                            lock (eventSync)
                            {
                                cachedBeObj.EventId = 0x19;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = "Version check passed.";

                                eventQueue.Enqueue(cachedBeObj);
                            }

                            if (botAccount.Product != BnetProduct.Warcraft3)
                            {
                                BnetPacket logonResponse2 = new BnetPacket();
                             
                                logonResponse2.InsertInt32(clientToken);
                                logonResponse2.InsertInt32(serverToken);
                                logonResponse2.InsertBytes(MBNCSUtil.OldAuth.DoubleHashPassword(botAccount.Password.ToLower(), clientToken, serverToken));
                                logonResponse2.InsertString(botAccount.Username);

                                SendPacket(0x3A, logonResponse2); // SID_LOGONRESPONSE2
                            }
                            else
                            {
                                logonChallengeRequestToken = new LogonChallengeRequestToken(botAccount.Username, botAccount.Password.ToLower(), botAccount.Product);
                                Messenger.Default.Register<IBnlsRequestToken>(this, logonChallengeRequestToken, true, ReceivedBnlsMessage);
                                BnlsService.Instance.BnlsLogonChallengeRequest(logonChallengeRequestToken);
                            }

                            break;
                        case 0x100:
                            lock (eventSync)
                            {
                                cachedBeObj.EventId = 0x13;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = "Old game version!";
                                eventQueue.Enqueue(cachedBeObj);
                            }
                            
                            // Disconnect();
                            break;
                        case 0x101:
                            lock (eventSync)
                            {
                                cachedBeObj.EventId = 0x13;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = "Invalid version!";

                                eventQueue.Enqueue(cachedBeObj);
                            }

                           // Disconnect();
                            break;
                        case 0x102:
                            lock (eventSync)
                            {
                                cachedBeObj.EventId = 0x13;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = "Game version must be downgraded!";
                                eventQueue.Enqueue(cachedBeObj);
                            }

                           // Disconnect();

                            break;
                        case 0x200:
                            lock (eventSync)
                            {
                                cachedBeObj.EventId = 0x13;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = "Invalid CD-Key!";

                                eventQueue.Enqueue(cachedBeObj);
                            }
                           // Disconnect();

                            break;
                        case 0x201:
                            lock (eventSync)
                            {
                                string user = dr.ReadString();
                                cachedBeObj.EventId = 0x13;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = string.Format("CD-Key in use by: {0}", user);

                                eventQueue.Enqueue(cachedBeObj);
                            }
                           // Disconnect();

                            break;
                        case 0x202:
                            lock (eventSync)
                            {
                                cachedBeObj.EventId = 0x13;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = "Banned CD-Key!";

                                eventQueue.Enqueue(cachedBeObj);
                            }
                           // Disconnect();

                            break;
                        case 0x203:
                            lock (eventSync)
                            {
                                cachedBeObj.EventId = 0x13;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = "Wrong product!";

                                eventQueue.Enqueue(cachedBeObj);
                            }

                           // Disconnect();

                            break;
                        default:
                            lock (eventSync)
                            {
                                System.Diagnostics.Debug.WriteLine("UKWN Result {0:X}", result);
                                cachedBeObj.EventId = 0x13;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = "Invalid version!";

                                eventQueue.Enqueue(cachedBeObj);
                            }
                           // Disconnect();

                            break;
                    }
                    

                    break;

                case 0x52:
                    int accountCreateResult = dr.ReadInt32();

                    switch (accountCreateResult)
                    {
                        case 0x00:
                            BnlsService.Instance.BnlsLogonChallengeRequest(logonChallengeRequestToken);

                            break;
                    }

                    break;

                case 0x53:
                    int accountLogonResult = dr.ReadInt32();

                    switch (accountLogonResult)
                    {
                        case 0x00:
                            int[] salt = dr.ReadInt32Array(8);
                            int[] serverKey = dr.ReadInt32Array(8);

                            logonProofRequestToken = new LogonProofRequestToken(salt, serverKey);
                            
                            Messenger.Default.Register<IBnlsRequestToken>(this, logonProofRequestToken, true, ReceivedBnlsMessage);
                            BnlsService.Instance.BnlsLogonProofRequest(logonProofRequestToken);

                            break;
                        case 0x01:
                            // Account doesn't exist. 
                            createAccountRequestToken = new CreateAccountRequestToken(botAccount.Username, botAccount.Password.ToLower());

                            Messenger.Default.Register<IBnlsRequestToken>(this, createAccountRequestToken, true, ReceivedBnlsMessage);
                            BnlsService.Instance.BnlsCreateAccountRequest(createAccountRequestToken);

                            break;
                        case 0x05:
                            // TODO:
                            break;
                    }

                    break;

                case 0x54:
                    int logonProofResult = dr.ReadInt32();

                    switch (logonProofResult)
                    {
                        case 0x00:
                            BnetPacket enterChat = new BnetPacket();
                            enterChat.InsertString(botAccount.Username);
                            enterChat.InsertString("");

                            SendPacket(0x0A, enterChat);

                            BnetPacket channelList = new BnetPacket();
                            channelList.InsertInt32(0);
    
                            SendPacket(0x0B, channelList);

                            BnetPacket joinChannel = new BnetPacket();

                            joinChannel.InsertInt32(0x02);
                            joinChannel.InsertString(botAccount.HomeChannel);

                            SendPacket(0x0C, joinChannel);

                            break;
                    
                        case 0x0E:
                            BnetPacket enterChat2 = new BnetPacket();
                            enterChat2.InsertString(botAccount.Username);
                            enterChat2.InsertString("");

                            SendPacket(0x0A, enterChat2);

                            BnetPacket channelList2 = new BnetPacket();
                            channelList2.InsertInt32(0);
    
                            SendPacket(0x0B, channelList2);

                            BnetPacket joinChannel2 = new BnetPacket();

                            joinChannel2.InsertInt32(0x02);
                            joinChannel2.InsertString(botAccount.HomeChannel);

                            SendPacket(0x0C, joinChannel2);

                            break;
                    }

                    break;
                case 0x3A:
                    int accountResult = dr.ReadInt32();

                    switch(accountResult)
                    {
                        case 0x00:
                            BnetPacket enterChat = new BnetPacket();
                            enterChat.InsertString(botAccount.Username);
                            enterChat.InsertString("");

                            SendPacket(0x0A, enterChat);

                            BnetPacket channelList = new BnetPacket();
                            channelList.InsertInt32(0);
    
                            SendPacket(0x0B, channelList);

                            BnetPacket joinChannel = new BnetPacket();

                            joinChannel.InsertInt32(0x02);
                            joinChannel.InsertString(botAccount.HomeChannel);

                            SendPacket(0x0C, joinChannel);

                            BnetPacket friendsList = new BnetPacket();
                            SendPacket(0x65, friendsList);
                            break;
                        case 0x01:
                            lock (eventSync)
                            {
                                cachedBeObj.EventId = 0x13;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = "Account does not exist!";
                                eventQueue.Enqueue(cachedBeObj);
                            }

                            // Account creation for legacy clients
                            BnetPacket createAccount = new BnetPacket();

                            createAccount.InsertBytes(MBNCSUtil.OldAuth.HashPassword(botAccount.Password));                            
                            createAccount.InsertString(botAccount.Username);
                            SendPacket(0x3D, createAccount);

                            break;
                        case 0x02:
                            lock (eventSync)
                            {
                                cachedBeObj.EventId = 0x13;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = "Invalid password!";

                                eventQueue.Enqueue(cachedBeObj);
                            }
                         //   Disconnect();

                            break;
                        case 0x06:
                            lock (eventSync)
                            {
                                cachedBeObj.EventId = 0x13;
                                cachedBeObj.Username = string.Empty;
                                cachedBeObj.Message = "Account closed!";

                                eventQueue.Enqueue(cachedBeObj);
                            }
                        //    Disconnect();

                            break;
                    }
                        
                    break;
                case 0x0B:
                    while (dr.PeekByte() != 0)
                    {
                        BnetEvent ber = new BnetEvent();
                        ber.EventId = 0x22; // EID_CHANNELLISTUSER
                        ber.Username = dr.ReadString();

                        Messenger.Default.Send<BnetEvent>(ber, connectionToken);
                    }

                    break;

                case 0x65:
                    int count = dr.ReadByte();
                    for (int i = 0; i < count; i++)
                    {
                        BnetFriend bf = new BnetFriend();
                        bf.Username = dr.ReadString();
                        byte status = dr.ReadByte();
                        byte friendLoc = dr.ReadByte();

                        string statusStr = string.Empty;
                        string locStr = string.Empty;

                        if (status == 0x00)
                            statusStr = "Friend";
                        else if (status == 0x01)
                            statusStr = "Friend (Mutual)";
                        else if (status == 0x02)
                            statusStr = "Friend (DND)";
                        else if (status == 0x04)
                            statusStr = "Friend (Away)";

                        if (friendLoc == 0x03)
                            locStr = ", in a public game.";
                        else if (friendLoc == 0x04 || friendLoc == 0x05)
                            locStr = ", in a private game.";
                        else
                            locStr = ", in a private channel.";

                        bf.Status = string.Format("{0}{1}", statusStr, locStr);
                        
                        dr.ReadInt32();
                        dr.ReadString();

                        Messenger.Default.Send<BnetFriend>(bf, connectionToken);
                    }

                    break;
                case 0x0A:
                    BnetPacket flPkt = new BnetPacket();
                    SendPacket(0x65, flPkt);

                    break;
                case 0x0F:
                    int eventId = dr.ReadInt32();
                    int flags = dr.ReadInt32();
                    int ping = dr.ReadInt32();
                   
                    dr.ReadInt32Array(3);

                    string username = dr.ReadString();
                    string message = dr.ReadString();

                    lock (eventSync)
                    {
                        BnetEvent cachedBeObj2 = new BnetEvent();
                        cachedBeObj2.EventId = eventId;
                        cachedBeObj2.Username = username;
                        cachedBeObj2.Message = message;
                        cachedBeObj2.Flags = flags;
                        cachedBeObj2.TimeStamp = DateTime.Now;

                        eventQueue.Enqueue(cachedBeObj2);
                    }

                    //Messenger.Default.Send<BnetEvent>(cachedBeObj2, connectionToken);
                    break;
                case 0x66:
                    // SID_FRIENDUPDATE
                    System.Diagnostics.Debug.WriteLine("Received Friend Update");
                    break;
            }
        }