private void HandleLogonRealmEx(PD data)
        {
            DataReader dr = new DataReader(data.Data);
            m_mcpCookie = dr.ReadInt32();
            int status = dr.ReadInt32();
            m_mcpStatus = status;

            if (data.Length > 8)
            {
                m_mcpChunk1 = dr.ReadByteArray(8);
                byte[] ipAddress = dr.ReadByteArray(4);
                m_ip = new IPAddress(ipAddress);
                m_port = dr.ReadInt32();
                m_mcpChunk2 = dr.ReadByteArray(48);
                m_uniqueBnetName = dr.ReadCString();

                BattleNetClientResources.IncomingBufferPool.FreeBuffer(data.Data);
            }
            else
            {
                RealmFailedEventArgs args = new RealmFailedEventArgs((RealmFailureReason)status) { EventData = data };
                OnRealmConnectionFailed(args);
            }
        }
Exemple #2
0
        internal Diablo2Stats(string userName, byte[] statstring)
        {
            m_literal = Encoding.ASCII.GetString(statstring);

            DataReader dr = new DataReader(statstring);
            string productCode = dr.ReadDwordString(0);
            m_prod = Product.GetByProductCode(productCode);
            if (m_prod == null)
                m_prod = Product.UnknownProduct;

            Match m = RealmCharacterTest.Match(userName);
            if (m.Success)
            {
                m_userName = string.Concat("*", m.Groups["Username"].Value);
                try
                {
                    m_isRealm = true;
                    m_realm = dr.ReadTerminatedString(',', Encoding.ASCII);
                    m_charName = dr.ReadTerminatedString(',', Encoding.ASCII);

                    byte[] characterData = dr.ReadByteArray(33);
                    /*
    0000   ff 0f 74 00 01 00 00 00 00 00 00 00 8c 00 00 00  ..t.............
    0010   00 00 00 00 0d f0 ad ba 0d f0 ad ba 53 63 72 65  ............Scre
    0020   65 6e 53 68 6f 6f 74 40 55 53 45 61 73 74 2a 44  enShoot@USEast*D
    0030   72 2e 4d 61 72 73 68 61 6c 6c 00 50 58 32 44 55  r.Marshall.PX2DU
    0040   53 45 61 73 74 2c 53 63 72 65 65 6e 53 68 6f 6f  SEast,ScreenShoo
    0050   74 2c>84 80 39 ff ff ff ff 0f ff 5d ff ff ff*04  t,..9......]....
    0060   4d ff ff ff ff ff ff ff ff ff ff 56*a8*9a ff ff  M..........V....
    0070   ff ff ff<00                                      ....
                     * */
                    m_class = (Diablo2CharacterClass)characterData[13];
                    if (m_class < Diablo2CharacterClass.Amazon || m_class > Diablo2CharacterClass.Assassin)
                        m_class = Diablo2CharacterClass.Unknown;

                    m_isMale = !(m_class == Diablo2CharacterClass.Amazon || m_class == Diablo2CharacterClass.Assassin ||
                                    m_class == Diablo2CharacterClass.Sorceress);

                    m_level = characterData[25];

                    byte flags = characterData[26];
                    m_isHardcore = ((flags & 4) == 4);
                    m_isDead = ((flags & 8) == 8);
                    m_isExpCharacter = ((flags & 32) == 32);
                    m_isLadder = ((flags & 64) == 64);

                    byte completedActs = (byte)((characterData[27] & 0x3e) >> 2);
                    if (m_isExpCharacter)
                    {
                        m_difficulty = (Diablo2DifficultyLevel)(completedActs / 5);
                        m_numActsCompleted = (completedActs % 5);
                        m_hasCompletedGame = (m_numActsCompleted == 5);
                    }
                    else
                    {
                        m_difficulty = (Diablo2DifficultyLevel)(completedActs / 4);
                        m_numActsCompleted = (completedActs % 4);
                        m_hasCompletedGame = (m_numActsCompleted == 4);
                    }
                }
                catch (ArgumentOutOfRangeException) { }
            }
            else
            {
                m_userName = userName;
            }
        }
        private void HandleAuthAccountLogon(ParseData data)
        {
            DataReader dr = new DataReader(data.Data);
            // 0x53
            // status codes:
            // 0: accepted, proof needed
            // 1: no such account
            // 5: upgrade account
            // else: unknown failure
            int status = dr.ReadInt32();

            if (status == 0)
            {
                byte[] salt = dr.ReadByteArray(32);
                byte[] serverKey = dr.ReadByteArray(32);

                BncsPacket pck0x54 = new BncsPacket((byte)BncsPacketId.AuthAccountLogonProof);
                m_nls.LoginProof(pck0x54, salt, serverKey);
                Send(pck0x54);
            }
            else
            {
                // create the account or error out.
                if (status == 1)
                {
                    OnInformation(new InformationEventArgs(
                        string.Format(CultureInfo.CurrentCulture, Strings.AccountDNECreating, m_settings.Username)));

                    BncsPacket pck0x52 = new BncsPacket((byte)BncsPacketId.AuthAccountCreate);
                    m_nls.CreateAccount(pck0x52);
                    Send(pck0x52);
                }
                else if (status == 5)
                {
                    OnError(new ErrorEventArgs(ErrorType.AccountUpgradeUnsupported, Strings.UpgradeRequestedUnsupported, true));
                    Close();
                    return;
                }
                else
                {
                    OnError(new ErrorEventArgs(ErrorType.InvalidUsernameOrPassword, Strings.InvalidUsernameOrPassword, true));
                    Close();
                    return;
                }
            }
        }
        private void HandleAuthAccountLogonProof(ParseData data)
        {
            DataReader dr = new DataReader(data.Data);

            int status = dr.ReadInt32();
            byte[] m2 = dr.ReadByteArray(20);
            // 0 = success
            // 2 = incorrect password
            // 14 = success; register e-mail
            // 15 = custom error
            switch (status)
            {
                case 0:
                    // success
                    if (!m_nls.VerifyServerProof(m2))
                    {
                        //CloseWithError(BattleNet.LoginProofServerProofFailed);
                        OnError(new ErrorEventArgs(ErrorType.LoginServerProofFailed, Strings.LoginProofServerProofFailed, false));
                        EnterChat();
                    }
                    else
                    {
                        OnInformation(new InformationEventArgs(Strings.LoginProofSuccess));
                        OnLoginSucceeded(BaseEventArgs.GetEmpty(null));
                        EnterChat();
                    }
                    break;
                case 2:
                    CloseWithError(Strings.LoginProofClientProofFailed, ErrorType.InvalidUsernameOrPassword);
                    break;
                case 14:
                    if (!m_nls.VerifyServerProof(m2))
                    {
                        OnError(new ErrorEventArgs(ErrorType.LoginServerProofFailed, Strings.LoginProofServerProofFailed, false));
                        EnterChat();
                    }
                    else
                    {
                        OnInformation(new InformationEventArgs(Strings.LoginProofRegisterEmail));
                        EnterChat();
                    }
                    break;
                case 15:
                    CloseWithError(
                        string.Format(CultureInfo.CurrentCulture, Strings.LoginProofCustomError, dr.ReadCString()),
                        ErrorType.InvalidUsernameOrPassword
                    );
                    break;
            }

            BattleNetClientResources.IncomingBufferPool.FreeBuffer(data.Data);
        }
        private void HandleAuthInfo(ParseData data)
        {
            try
            {
                DataReader dr = new DataReader(data.Data);
                if (m_pingPck != null)
                {
                    Send(m_pingPck);
                    m_pingPck = null;
                }
                m_received0x50 = true;

                m_loginType = dr.ReadUInt32();
                m_srvToken = dr.ReadUInt32();
                m_udpVal = dr.ReadUInt32();
                m_mpqFiletime = dr.ReadInt64();
                m_versioningFilename = dr.ReadCString();
                m_usingLockdown = m_versioningFilename.StartsWith("LOCKDOWN", StringComparison.OrdinalIgnoreCase);

                int crResult = -1, exeVer = -1;
                string exeInfo = null;

                if (!m_usingLockdown)
                {
                    m_valString = dr.ReadCString();
                    int mpqNum = CheckRevision.ExtractMPQNumber(m_versioningFilename);
                    crResult = CheckRevision.DoCheckRevision(m_valString, new string[] { m_settings.GameExe, m_settings.GameFile2, m_settings.GameFile3 }, mpqNum);
                    exeVer = CheckRevision.GetExeInfo(m_settings.GameExe, out exeInfo);
                }
                else
                {
                    m_ldValStr = dr.ReadNullTerminatedByteArray();
                    string dllName = m_versioningFilename.Replace(".mpq", ".dll");

                    BnFtpVersion1Request req = new BnFtpVersion1Request(m_settings.Client, m_versioningFilename, null);
                    req.Server = m_settings.Gateway.ServerHost;
                    req.LocalFileName = Path.Combine(Path.GetTempPath(), m_versioningFilename);
                    req.ExecuteRequest();

                    string ldPath = null;
                    using (MpqArchive arch = MpqServices.OpenArchive(req.LocalFileName))
                    {
                        if (arch.ContainsFile(dllName))
                        {
                            ldPath = Path.Combine(Path.GetTempPath(), dllName);
                            arch.SaveToPath(dllName, Path.GetTempPath(), false);
                        }
                    }

                    m_ldDigest = CheckRevision.DoLockdownCheckRevision(m_ldValStr, new string[] { m_settings.GameExe, m_settings.GameFile2, m_settings.GameFile3 },
                                    ldPath, m_settings.ImageFile, ref exeVer, ref crResult);
                }

                m_prodCode = m_settings.Client;

                if (m_prodCode == "WAR3" ||
                    m_prodCode == "W3XP")
                {
                    m_w3srv = dr.ReadByteArray(128);

                    if (!NLS.ValidateServerSignature(m_w3srv, RemoteEP.Address.GetAddressBytes()))
                    {
                        OnError(new ErrorEventArgs(ErrorType.Warcraft3ServerValidationFailure, Strings.War3ServerValidationFailed, false));
                        //Close();
                        //return;
                    }
                }

                BattleNetClientResources.IncomingBufferPool.FreeBuffer(data.Data);

                CdKey key1, key2 = null;
                key1 = new CdKey(m_settings.CdKey1);
                if (m_prodCode == "D2XP" || m_prodCode == "W3XP")
                {
                    key2 = new CdKey(m_settings.CdKey2);
                }

                m_clientToken = unchecked((uint)new Random().Next());

                byte[] key1Hash = key1.GetHash(m_clientToken, m_srvToken);
                if (m_warden != null)
                {
                    try
                    {
                        if (!m_warden.InitWarden(BitConverter.ToInt32(key1Hash, 0)))
                        {
                            m_warden.UninitWarden();
                            OnError(new ErrorEventArgs(ErrorType.WardenModuleFailure, "The Warden module failed to initialize.  You will not be immediately disconnected; however, you may be disconnected after a short period of time.", false));
                            m_warden = null;
                        }
                    }
                    catch (Win32Exception we)
                    {
                        OnError(new ErrorEventArgs(ErrorType.WardenModuleFailure, "The Warden module failed to initialize.  You will not be immediately disconnected; however, you may be disconnected after a short period of time.", false));
                        OnError(new ErrorEventArgs(ErrorType.WardenModuleFailure, string.Format(CultureInfo.CurrentCulture, "Additional information: {0}", we.Message), false));
                        m_warden.UninitWarden();
                        m_warden = null;
                    }
                }

                BncsPacket pck0x51 = new BncsPacket((byte)BncsPacketId.AuthCheck);
                pck0x51.Insert(m_clientToken);
                pck0x51.Insert(exeVer);
                pck0x51.Insert(crResult);
                if (m_prodCode == "D2XP" || m_prodCode == "W3XP")
                    pck0x51.Insert(2);
                else
                    pck0x51.Insert(1);
                pck0x51.Insert(false);
                pck0x51.Insert(key1.Key.Length);
                pck0x51.Insert(key1.Product);
                pck0x51.Insert(key1.Value1);
                pck0x51.Insert(0);
                pck0x51.Insert(key1Hash);
                if (key2 != null)
                {
                    pck0x51.Insert(key2.Key.Length);
                    pck0x51.Insert(key2.Product);
                    pck0x51.Insert(key2.Value1);
                    pck0x51.Insert(0);
                    pck0x51.Insert(key2.GetHash(m_clientToken, m_srvToken));
                }

                if (m_usingLockdown)
                {
                    pck0x51.InsertByteArray(m_ldDigest);
                    pck0x51.InsertByte(0);
                }
                else
                    pck0x51.InsertCString(exeInfo);

                pck0x51.InsertCString(m_settings.CdKeyOwner);

                Send(pck0x51);
            }
            catch (Exception ex)
            {
                OnError(new ErrorEventArgs(ErrorType.General, "There was an error while initializing your client.  Refer to the exception message for more information.\n" + ex.ToString(), true));
                Close();
            }
        }