// 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)); }
private static int ExecutePreloadedRevisionCheck( string valueString, string[] files, int mpqNumber) { uint A, B, C; List <string> formulas = new List <string>(); CheckRevisionFormulaTracker.InitializeValues(valueString, formulas, out A, out B, out C); A ^= hashcodes[mpqNumber]; Stream dataStream = CheckRevisionPreloadTracker.GetFiles(files); int result = DoCheckRevisionCompiled(A, B, C, formulas, dataStream); if (OptimizationStrategy == CheckRevisionOptimizationStrategy.PreloadAllFilesAndClearAfterUse) { dataStream.Dispose(); dataStream = null; } return(result); }
// This method always assumes the inputs have been sanity-checked. private static int SlowCheckRevision( string valueString, string[] files, int mpqNumber) { uint[] values = new uint[4]; int[] opValueDest = new int[4]; int[] opValueSrc1 = new int[4]; char[] operation = new char[4]; int[] opValueSrc2 = new int[4]; string[] tokens = valueString.Split(new char[] { ' ' }); int currentFormula = 0; // while (stringTokenizer.hasMoreTokens()) for (int i = 0; i < tokens.Length; i++) { string token = tokens[i]; // as long as there is a '=' in the string if (token.IndexOf('=') != -1) { string[] nameTokens = token.Split(new char[] { '=' }); if (nameTokens.Length != 2) { return(0); } int variable = getNum(nameTokens[0][0]); string value = nameTokens[1]; // If it starts with a number, assign that number to the appropriate variable if (char.IsDigit(value[0])) { values[variable] = uint.Parse(value, CultureInfo.InvariantCulture); } else { opValueDest[currentFormula] = variable; opValueSrc1[currentFormula] = getNum(value[0]); operation[currentFormula] = value[1]; opValueSrc2[currentFormula] = getNum(value[2]); currentFormula++; } } } // Now we actually do the hashing for each file // Start by hashing A by the hashcode values[0] ^= hashcodes[mpqNumber]; byte[] currentOperandBuffer = new byte[1024]; for (int i = 0; i < files.Length; i++) { using (FileStream currentFile = new FileStream(files[i], FileMode.Open, FileAccess.Read, FileShare.Read)) { while (currentFile.Position < currentFile.Length) { long currentFilePosition = 0; long amountToRead = Math.Min(currentFile.Length - currentFile.Position, 1024); currentFile.Read(currentOperandBuffer, 0, (int)amountToRead); if (amountToRead < 1024) { byte currentPaddingByte = 0xff; for (int j = (int)amountToRead; j < 1024; j++) { unchecked { currentOperandBuffer[j] = currentPaddingByte--; } } } CheckRevisionFormulaTracker.FileAppendBytes("c:\\projects\\baseline.bin", currentOperandBuffer); for (int j = 0; j < 1024; j += 4) { values[3] = BitConverter.ToUInt32(currentOperandBuffer, j); for (int k = 0; k < currentFormula; k++) { switch (operation[k]) { case '+': values[opValueDest[k]] = values[opValueSrc1[k]] + values[opValueSrc2[k]]; break; case '-': values[opValueDest[k]] = values[opValueSrc1[k]] - values[opValueSrc2[k]]; break; case '^': values[opValueDest[k]] = values[opValueSrc1[k]] ^ values[opValueSrc2[k]]; break; case '*': // as shady said, you never know. values[opValueDest[k]] = values[opValueSrc1[k]] * values[opValueSrc2[k]]; break; case '/': // in case blizz gets "sneaky" values[opValueDest[k]] = values[opValueSrc1[k]] / values[opValueSrc2[k]]; break; } } } } } } return(unchecked ((int)values[2])); }