/// <summary> /// Calculates the revision check for the specified files. /// </summary> /// <param name="valueString">The value string for the check revision function specified by Battle.net's SID_AUTH_INFO message.</param> /// <param name="files">The list of files for the given game client. This parameter must be exactly three files long.</param> /// <param name="mpqNumber">The number of the MPQ file. To extract this number, see the /// <see cref="ExtractMPQNumber(String)">ExtractMPQNumber</see> method.</param> /// <returns>The checksum value.</returns> /// <exception cref="ArgumentNullException">Thrown if the <i>valueString</i> or <i>files</i> parameters are <b>null</b> /// (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="files" /> is not a 3-string array, or if /// <paramref name="mpqNumber" /> is outside of the range of 0 to 7, inclusive.</exception> /// <exception cref="FileNotFoundException">Thrown if one of the specified game files is not found.</exception> /// <exception cref="IOException">Thrown in the event of a general I/O error.</exception> /// <remarks> /// <para>The file list for this is product-specific and order-specific:</para> /// <list type="table"> /// <listheader> /// <term>Product</term> /// <description>File list</description> /// </listheader> /// <item> /// <term>Starcraft; Starcraft: Brood War</term> /// <description> /// <list type="bullet"> /// <item> /// <description>Starcraft.exe</description> /// </item> /// <item> /// <description>storm.dll</description> /// </item> /// <item> /// <description>battle.snp</description> /// </item> /// </list> /// </description> /// </item> /// <item> /// <term>Warcraft II: Battle.net Edition</term> /// <description> /// <list type="bullet"> /// <item> /// <description>Warcraft II BNE.exe</description> /// </item> /// <item> /// <description>storm.dll</description> /// </item> /// <item> /// <description>battle.snp</description> /// </item> /// </list> /// </description> /// </item> /// <item> /// <term>Diablo II; Diablo II: Lord of Destruction</term> /// <description> /// <list type="bullet"> /// <item> /// <description>Game.exe</description> /// </item> /// <item> /// <description>Bnclient.dll</description> /// </item> /// <item> /// <description>D2Client.dll</description> /// </item> /// </list> /// </description> /// </item> /// <item> /// <term>Warcraft III: The Reign of Chaos; Warcraft III: The Frozen Throne</term> /// <description> /// <list type="bullet"> /// <item> /// <description>War3.exe</description> /// </item> /// <item> /// <description>storm.dll</description> /// </item> /// <item> /// <description>Game.dll</description> /// </item> /// </list> /// </description> /// </item> /// </list> /// </remarks> public static int DoCheckRevision( string valueString, IEnumerable <Stream> files, int mpqNumber) { if (valueString == null) { throw new ArgumentNullException("valueString"); } if (files == null) { throw new ArgumentNullException("files"); } if (files.Count() != 3) { throw new ArgumentOutOfRangeException("files", files, "The file list is invalid."); } if (mpqNumber < 0 || mpqNumber > 7) { throw new ArgumentOutOfRangeException("mpqNumber", mpqNumber, "MPQ number must be between 0 and 7, inclusive."); } using (Stream crStream = new CheckRevisionStream(files)) { uint A, B, C; List <string> formulas = new List <string>(); CheckRevisionFormulaTracker.InitializeValues(valueString, formulas, out A, out B, out C); A ^= hashcodes[mpqNumber]; int result = DoCheckRevisionCompiled(A, B, C, formulas, crStream); return(result); } }
// This method assumes all parameters have been sanity checked private static int DoCheckRevisionCompiled( uint A, uint B, uint C, IEnumerable <string> crevFormulas, Stream completeDataStream) { StandardCheckRevisionImplementation impl = CheckRevisionFormulaTracker.GetImplementation(crevFormulas); using (BinaryReader br = new BinaryReader(completeDataStream)) { uint S; while (br.BaseStream.Position < br.BaseStream.Length) { S = br.ReadUInt32(); impl(ref A, ref B, ref C, ref S); } } return(unchecked ((int)C)); }