private static void ArrayRepeatPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext) { readingContext.pattern.TakeArg(); Int32 scaledElementSize; // Some element types have no context-free size determination apart from assumed elements total size and count. // Also ignore it if we have 0 elements because it is pointless and causes exception. if (readingContext.pattern[0] == ExportParsingMachine.scaledArrayElementsPatternElementName && readingContext.collectionElementCount != 0) { readingContext.pattern.TakeArg(); scaledElementSize = (readingContext.declaredSizeStartOffset + readingContext.declaredSize - readingContext.currentUexpOffset) / (readingContext.collectionElementCount); } else { scaledElementSize = -1; } List <string> repeatedPattern = new List <string>(); // Passing all the stuff to repeat in cycle which is all past ArrayRepeat and til ArrayRepeatEnd or end of pattern while (readingContext.pattern.Count > 0) { string element = readingContext.pattern.TakeArg(); if (element == ExportParsingMachine.arrayRepeatEndPatternElementName) { break; } repeatedPattern.Add(element); } for (int i = 0; i < readingContext.collectionElementCount; i++) { ExportParsingMachine.ReportExportContents($"Element {i}"); ExportParsingMachine.machineState.Push(new ReadingContext() { currentUexpOffset = readingContext.currentUexpOffset, pattern = new List <string>(repeatedPattern), patternAlphabet = readingContext.patternAlphabet, structCategory = ReadingContext.StructCategory.nonExport, declaredSize = scaledElementSize }); ExportParsingMachine.ExecutePushedReadingContext(uasset, uexp, readingContext); } }
private static void NoneTerminatedPropListPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext) { string substructName = ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset); readingContext.currentUexpOffset += 8; if (substructName == ExportParsingMachine.endOfStructConfigName) { readingContext.pattern.TakeArg(); return; } string typeName = ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset); readingContext.currentUexpOffset += 8; ExportParsingMachine.ReportExportContents("------------------------------"); ExportParsingMachine.ReportExportContents($"{substructName} is {typeName}"); List <string> propertyPattern; try { propertyPattern = Program.GetPattern($"{Program.PatternFolders.property}/{typeName}"); } catch { ExportParsingMachine.ReportExportContents($"Failed to find a pattern for property type {typeName}"); Int32 assumedSize = BitConverter.ToInt32(uexp, readingContext.currentUexpOffset); readingContext.currentUexpOffset += 8; ExportParsingMachine.ReportExportContents($"Assumed property size {assumedSize}"); ExportParsingMachine.ReportExportContents($"Assumed property body {BitConverter.ToString(uexp, readingContext.currentUexpOffset + 1, assumedSize)}"); throw; } ExportParsingMachine.machineState.Push(new ReadingContext() { currentUexpOffset = readingContext.currentUexpOffset, declaredSize = -1, declaredSizeStartOffset = -1, collectionElementCount = -1, pattern = propertyPattern, patternAlphabet = readingContext.patternAlphabet, structCategory = ReadingContext.StructCategory.nonExport }); ExportParsingMachine.ExecutePushedReadingContext(uasset, uexp, readingContext); }
private static void ArrayRepeatContextSearcher(byte[] uasset, byte[] uexp, ReadingContext readingContext) { readingContext.pattern.TakeArg(); bool thisArrayIsTarget = false; Int32 targetIndex = -1; if (readingContext.targetContext.Count > 2) { if (readingContext.targetContext[0] == "Array") { Int32 skipsLeft = Int32.Parse(readingContext.targetContext[1]); if (skipsLeft == 0) { thisArrayIsTarget = true; readingContext.targetContext.TakeArg(); readingContext.targetContext.TakeArg(); targetIndex = Int32.Parse(readingContext.targetContext.TakeArg()); } else { skipsLeft--; readingContext.targetContext[1] = skipsLeft.ToString(); } } } Int32 scaledElementSize; // Some element types have no context-free size determination apart from assumed elements total size and count. // Also ignore it if we have 0 elements because it is pointless and causes exception. if (readingContext.pattern[0] == ExportParsingMachine.scaledArrayElementsPatternElementName && readingContext.collectionElementCount != 0) { readingContext.pattern.TakeArg(); scaledElementSize = (readingContext.declaredSizeStartOffset + readingContext.declaredSize - readingContext.currentUexpOffset) / (readingContext.collectionElementCount); } else { scaledElementSize = -1; } List <string> repeatedPattern = new List <string>(); // Passing all the stuff to repeat in cycle which is all past ArrayRepeat and til ArrayRepeatEnd or end of pattern while (readingContext.pattern.Count > 0) { string element = readingContext.pattern.TakeArg(); if (element == ExportParsingMachine.arrayRepeatEndPatternElementName) { break; } repeatedPattern.Add(element); } for (int i = 0; i < readingContext.collectionElementCount; i++) { if (customRunDara.reportSearchSteps) { ExportParsingMachine.ReportExportContents($"Element {i}"); } ExportParsingMachine.machineState.Push(new ReadingContext() { currentUexpOffset = readingContext.currentUexpOffset, pattern = new List <string>(repeatedPattern), patternAlphabet = readingContext.patternAlphabet, targetContext = thisArrayIsTarget && (i == targetIndex) ? readingContext.targetContext : new List <string>() { "Pattern Blocker" }, structCategory = ReadingContext.StructCategory.nonExport, declaredSize = scaledElementSize, contextReturnProcesser = ContextReturnProcesser }); ExportParsingMachine.ExecutePushedReadingContext(uasset, uexp, readingContext); } }
private static void NTPLContextSearcher(byte[] uasset, byte[] uexp, ReadingContext readingContext) { string targetPropertyName = readingContext.targetContext[0]; string substructName = ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset); readingContext.currentUexpOffset += 8; if (substructName == ExportParsingMachine.endOfStructConfigName) { readingContext.pattern.TakeArg(); return; } string typeName = ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset); readingContext.currentUexpOffset += 8; if (customRunDara.reportSearchSteps) { ExportParsingMachine.ReportExportContents("------------------------------"); ExportParsingMachine.ReportExportContents($"{substructName} is {typeName}"); } List <string> propertyPattern; try { propertyPattern = Program.GetPattern($"{Program.PatternFolders.property}/{typeName}"); } catch { ExportParsingMachine.ReportExportContents($"Failed to find a pattern for property type {typeName}"); Int32 assumedSize = BitConverter.ToInt32(uexp, readingContext.currentUexpOffset); readingContext.currentUexpOffset += 8; ExportParsingMachine.ReportExportContents($"Assumed property size {assumedSize}"); ExportParsingMachine.ReportExportContents($"Assumed property body {BitConverter.ToString(uexp, readingContext.currentUexpOffset + 1, assumedSize)}"); throw; } if (substructName != targetPropertyName) { propertyPattern.Insert(propertyPattern.IndexOf(ExportParsingMachine.sizeStartPatternElementName) + 1, skipContextPatternElementName); } List <string> targetSubContext = new List <string>(readingContext.targetContext); targetSubContext.RemoveAt(0); ExportParsingMachine.machineState.Push(new ReadingContext() { currentUexpOffset = readingContext.currentUexpOffset, declaredSize = -1, declaredSizeStartOffset = -1, collectionElementCount = -1, targetContext = targetSubContext, pattern = propertyPattern, patternAlphabet = readingContext.patternAlphabet, structCategory = ReadingContext.StructCategory.nonExport, contextReturnProcesser = ContextReturnProcesser }); ExportParsingMachine.ExecutePushedReadingContext(uasset, uexp, readingContext); }