private static List<DemoInfo> ParseDemosImpl(ref udtParseArg parseArg, List<string> filePaths, int maxThreadCount, int inputIndexBase) { var errorCodeArray = new Int32[filePaths.Count]; var filePathArray = new IntPtr[filePaths.Count]; for(var i = 0; i < filePaths.Count; ++i) { filePathArray[i] = Marshal.StringToHGlobalAnsi(Path.GetFullPath(filePaths[i])); } var pinnedPlugIns = new PinnedObject(PlugInArray); parseArg.PlugInCount = (UInt32)PlugInArray.Length; parseArg.PlugIns = pinnedPlugIns.Address; var pinnedFilePaths = new PinnedObject(filePathArray); var pinnedErrorCodes = new PinnedObject(errorCodeArray); var multiParseArg = new udtMultiParseArg(); multiParseArg.FileCount = (UInt32)filePathArray.Length; multiParseArg.FilePaths = pinnedFilePaths.Address; multiParseArg.OutputErrorCodes = pinnedErrorCodes.Address; multiParseArg.MaxThreadCount = (UInt32)maxThreadCount; udtParserContextGroupRef contextGroup = IntPtr.Zero; var result = udtParseDemoFiles(ref contextGroup, ref parseArg, ref multiParseArg); pinnedPlugIns.Free(); pinnedFilePaths.Free(); pinnedErrorCodes.Free(); for(var i = 0; i < filePathArray.Length; ++i) { Marshal.FreeHGlobal(filePathArray[i]); } if(result != udtErrorCode.None && result != udtErrorCode.OperationCanceled) { udtDestroyContextGroup(contextGroup); App.GlobalLogError("Failed to parse demos: " + GetErrorCodeString(result)); return null; } uint contextCount = 0; if(udtGetContextCountFromGroup(contextGroup, ref contextCount) != udtErrorCode.None) { udtDestroyContextGroup(contextGroup); return null; } var infoList = new List<DemoInfo>(); for(uint i = 0; i < contextCount; ++i) { udtParserContextRef context = IntPtr.Zero; if(udtGetContextFromGroup(contextGroup, i, ref context) != udtErrorCode.None) { udtDestroyContextGroup(contextGroup); return null; } uint demoCount = 0; if(udtGetDemoCountFromContext(context, ref demoCount) != udtErrorCode.None) { udtDestroyContextGroup(contextGroup); return null; } for(uint j = 0; j < demoCount; ++j) { uint inputIdx = 0; if(udtGetDemoInputIndex(context, j, ref inputIdx) != udtErrorCode.None) { continue; } var errorCode = errorCodeArray[(int)inputIdx]; if(errorCode != (Int32)udtErrorCode.None) { if(errorCode != (Int32)udtErrorCode.Unprocessed && errorCode != (Int32)udtErrorCode.OperationCanceled) { var fileName = Path.GetFileName(filePaths[(int)inputIdx]); var errorCodeString = GetErrorCodeString((udtErrorCode)errorCode); App.GlobalLogError("Failed to parse demo file {0}: {1}", fileName, errorCodeString); } continue; } var filePath = filePaths[(int)inputIdx]; var protocol = udtGetProtocolByFilePath(filePath); var info = new DemoInfo(); info.Analyzed = true; info.InputIndex = inputIndexBase + (int)inputIdx; info.FilePath = Path.GetFullPath(filePath); info.Protocol = UDT_DLL.GetProtocolAsString(protocol); ExtractDemoInfo(context, j, ref info); infoList.Add(info); } } udtDestroyContextGroup(contextGroup); // Keep the original input order. infoList.Sort((a, b) => a.InputIndex - b.InputIndex); return infoList; }
private static bool ConvertDemosImpl(ref udtParseArg parseArg, udtProtocol outProtocol, List<MapConversionRule> mapRules, List<string> filePaths, int maxThreadCount) { var resources = new ArgumentResources(); var errorCodeArray = new Int32[filePaths.Count]; var filePathArray = new IntPtr[filePaths.Count]; for(var i = 0; i < filePaths.Count; ++i) { var filePath = Marshal.StringToHGlobalAnsi(Path.GetFullPath(filePaths[i])); filePathArray[i] = filePath; resources.GlobalAllocationHandles.Add(filePath); } var pinnedFilePaths = new PinnedObject(filePathArray); var pinnedErrorCodes = new PinnedObject(errorCodeArray); resources.PinnedObjects.Add(pinnedFilePaths); resources.PinnedObjects.Add(pinnedErrorCodes); var multiParseArg = new udtMultiParseArg(); multiParseArg.FileCount = (UInt32)filePathArray.Length; multiParseArg.FilePaths = pinnedFilePaths.Address; multiParseArg.OutputErrorCodes = pinnedErrorCodes.Address; multiParseArg.MaxThreadCount = (UInt32)maxThreadCount; var conversionArg = new udtProtocolConversionArg(); conversionArg.OutputProtocol = (UInt32)outProtocol; conversionArg.MapRules = IntPtr.Zero; conversionArg.MapRuleCount = 0; if(mapRules.Count > 0) { var mapRuleArray = new udtMapConversionRule[mapRules.Count]; for(var i = 0; i < mapRules.Count; ++i) { var inputName = Marshal.StringToHGlobalAnsi(mapRules[i].InputName); var outputName = Marshal.StringToHGlobalAnsi(mapRules[i].OutputName); mapRuleArray[i].InputName = inputName; mapRuleArray[i].OutputName = outputName; mapRuleArray[i].PositionOffsetX = mapRules[i].OffsetX; mapRuleArray[i].PositionOffsetY = mapRules[i].OffsetY; mapRuleArray[i].PositionOffsetZ = mapRules[i].OffsetZ; resources.GlobalAllocationHandles.Add(inputName); resources.GlobalAllocationHandles.Add(outputName); } var pinnedMapRules = new PinnedObject(mapRuleArray); resources.PinnedObjects.Add(pinnedMapRules); conversionArg.MapRules = pinnedMapRules.Address; conversionArg.MapRuleCount = (UInt32)mapRuleArray.Length; } var result = udtErrorCode.OperationFailed; try { result = udtConvertDemoFiles(ref parseArg, ref multiParseArg, ref conversionArg); } finally { resources.Free(); } return result != udtErrorCode.None; }
private static bool CutDemosByPatternImpl(ArgumentResources resources, ref udtParseArg parseArg, List<string> filePaths, udtPatternInfo[] patterns, CutByPatternOptions options) { var errorCodeArray = new Int32[filePaths.Count]; var filePathArray = new IntPtr[filePaths.Count]; for(var i = 0; i < filePaths.Count; ++i) { filePathArray[i] = Marshal.StringToHGlobalAnsi(Path.GetFullPath(filePaths[i])); resources.GlobalAllocationHandles.Add(filePathArray[i]); } parseArg.PlugInCount = 0; parseArg.PlugIns = IntPtr.Zero; var pinnedFilePaths = new PinnedObject(filePathArray); var pinnedErrorCodes = new PinnedObject(errorCodeArray); var multiParseArg = new udtMultiParseArg(); multiParseArg.FileCount = (UInt32)filePathArray.Length; multiParseArg.FilePaths = pinnedFilePaths.Address; multiParseArg.OutputErrorCodes = pinnedErrorCodes.Address; multiParseArg.MaxThreadCount = (UInt32)options.MaxThreadCount; var playerNameUnmanaged = IntPtr.Zero; if(!string.IsNullOrEmpty(options.PlayerName)) { playerNameUnmanaged = Marshal.StringToHGlobalAnsi(options.PlayerName); resources.GlobalAllocationHandles.Add(playerNameUnmanaged); } var pinnedPatterns = new PinnedObject(patterns); var cutByPatternArg = new udtCutByPatternArg(); cutByPatternArg.StartOffsetSec = (UInt32)options.StartOffset; cutByPatternArg.EndOffsetSec = (UInt32)options.EndOffset; cutByPatternArg.Patterns = pinnedPatterns.Address; cutByPatternArg.PatternCount = (UInt32)patterns.Length; cutByPatternArg.PlayerIndex = options.PlayerIndex; cutByPatternArg.PlayerName = playerNameUnmanaged; cutByPatternArg.Flags = 0; if(options.MergeCutSections) { cutByPatternArg.Flags |= (UInt32)udtCutByPatternArgFlags.MergeCutSections; } resources.PinnedObjects.Add(pinnedPatterns); resources.PinnedObjects.Add(pinnedFilePaths); resources.PinnedObjects.Add(pinnedErrorCodes); udtErrorCode result = udtErrorCode.OperationFailed; try { result = udtCutDemoFilesByPattern(ref parseArg, ref multiParseArg, ref cutByPatternArg); } finally { resources.Free(); } return result == udtErrorCode.None; }
public static List<DemoInfo> ParseDemos(ref udtParseArg parseArg, List<string> filePaths, int maxThreadCount) { var timer = new Stopwatch(); timer.Start(); var fileCount = filePaths.Count; if(fileCount <= MaxBatchSizeParsing) { var result = ParseDemosImpl(ref parseArg, filePaths, maxThreadCount, 0); PrintExecutionTime(timer); return result; } var oldProgressCb = parseArg.ProgressCb; var progressBase = 0.0f; var progressRange = 0.0f; var fileIndex = 0; var newParseArg = parseArg; newParseArg.ProgressCb = delegate(float progress, IntPtr userData) { var realProgress = progressBase + progressRange * progress; oldProgressCb(realProgress, userData); }; var demos = new List<DemoInfo>(); var batchCount = (fileCount + MaxBatchSizeParsing - 1) / MaxBatchSizeParsing; var filesPerBatch = fileCount / batchCount; for(int i = 0; i < batchCount; ++i) { progressBase = (float)fileIndex / (float)fileCount; var currentFileCount = (i == batchCount - 1) ? (fileCount - fileIndex) : filesPerBatch; var currentFiles = filePaths.GetRange(fileIndex, currentFileCount); progressRange = (float)currentFileCount / (float)fileCount; var currentResults = ParseDemosImpl(ref newParseArg, currentFiles, maxThreadCount, fileIndex); demos.AddRange(currentResults); fileIndex += currentFileCount; if(Marshal.ReadInt32(parseArg.CancelOperation) != 0) { break; } } PrintExecutionTime(timer); return demos; }
public static bool SplitDemo(udtParserContextRef context, ref udtParseArg parseArg, string filePath) { if(context == IntPtr.Zero) { return false; } parseArg.PlugInCount = 0; parseArg.PlugIns = IntPtr.Zero; return udtSplitDemoFile(context, ref parseArg, filePath) == udtErrorCode.None; }
public static bool CutDemosByMultiRail(ref udtParseArg parseArg, List<string> filePaths, udtCutByMultiRailArg rules, CutByPatternOptions options) { var resources = new ArgumentResources(); var patterns = new udtPatternInfo[1]; if(!CreateMultiRailPatternInfo(ref patterns[0], resources, rules)) { return false; } return CutDemosByPattern(resources, ref parseArg, filePaths, patterns, options); }
public static bool CutDemosByPattern(ArgumentResources resources, ref udtParseArg parseArg, List<string> filePaths, udtPatternInfo[] patterns, CutByPatternOptions options) { var timer = new Stopwatch(); timer.Start(); var fileCount = filePaths.Count; if(fileCount <= MaxBatchSizeCutting) { var result = CutDemosByPatternImpl(resources, ref parseArg, filePaths, patterns, options); PrintExecutionTime(timer); return result; } var oldProgressCb = parseArg.ProgressCb; var progressBase = 0.0f; var progressRange = 0.0f; var fileIndex = 0; var newParseArg = parseArg; newParseArg.ProgressCb = delegate(float progress, IntPtr userData) { var realProgress = progressBase + progressRange * progress; oldProgressCb(realProgress, userData); }; var demos = new List<DemoInfo>(); var batchCount = (fileCount + MaxBatchSizeCutting - 1) / MaxBatchSizeCutting; var filesPerBatch = fileCount / batchCount; var success = true; for(int i = 0; i < batchCount; ++i) { progressBase = (float)fileIndex / (float)fileCount; var currentFileCount = (i == batchCount - 1) ? (fileCount - fileIndex) : filesPerBatch; var currentFiles = filePaths.GetRange(fileIndex, currentFileCount); progressRange = (float)currentFileCount / (float)fileCount; var newResources = new ArgumentResources(); CutDemosByPatternImpl(newResources, ref newParseArg, currentFiles, patterns, options); fileIndex += currentFileCount; if(Marshal.ReadInt32(parseArg.CancelOperation) != 0) { success = false; break; } } resources.Free(); PrintExecutionTime(timer); return success; }
public static bool ConvertDemos(ref udtParseArg parseArg, udtProtocol outProtocol, List<MapConversionRule> mapRules, List<string> filePaths, int maxThreadCount) { var timer = new Stopwatch(); timer.Start(); var fileCount = filePaths.Count; if(fileCount <= MaxBatchSizeConverting) { var result = ConvertDemosImpl(ref parseArg, outProtocol, mapRules, filePaths, maxThreadCount); PrintExecutionTime(timer); return result; } var oldProgressCb = parseArg.ProgressCb; var progressBase = 0.0f; var progressRange = 0.0f; var fileIndex = 0; var newParseArg = parseArg; newParseArg.ProgressCb = delegate(float progress, IntPtr userData) { var realProgress = progressBase + progressRange * progress; oldProgressCb(realProgress, userData); }; var batchCount = (fileCount + MaxBatchSizeConverting - 1) / MaxBatchSizeConverting; var filesPerBatch = fileCount / batchCount; for(int i = 0; i < batchCount; ++i) { progressBase = (float)fileIndex / (float)fileCount; var currentFileCount = (i == batchCount - 1) ? (fileCount - fileIndex) : filesPerBatch; var currentFiles = filePaths.GetRange(fileIndex, currentFileCount); progressRange = (float)currentFileCount / (float)fileCount; fileIndex += currentFileCount; ConvertDemosImpl(ref newParseArg, outProtocol, mapRules, currentFiles, maxThreadCount); if(Marshal.ReadInt32(parseArg.CancelOperation) != 0) { break; } } PrintExecutionTime(timer); return true; }
public static bool CutDemoByTime(udtParserContextRef context, ref udtParseArg parseArg, string filePath, int startTimeSec, int endTimeSec) { if(context == IntPtr.Zero) { return false; } parseArg.PlugInCount = 0; parseArg.PlugIns = IntPtr.Zero; var cut = new udtCut(); cut.GameStateIndex = parseArg.GameStateIndex; cut.StartTimeMs = startTimeSec * 1000; cut.EndTimeMs = endTimeSec * 1000; var pinnedCut = new PinnedObject(cut); var cutInfo = new udtCutByTimeArg(); cutInfo.Cuts = pinnedCut.Address; cutInfo.CutCount = 1; var success = udtCutDemoFileByTime(context, ref parseArg, ref cutInfo, filePath) == udtErrorCode.None; pinnedCut.Free(); return success; }
private static extern udtErrorCode udtSplitDemoFile(udtParserContextRef context, ref udtParseArg info, string demoFilePath);
private static extern udtErrorCode udtParseDemoFiles(ref udtParserContextGroupRef contextGroup, ref udtParseArg info, ref udtMultiParseArg extraInfo);
private static extern udtErrorCode udtCutDemoFilesByPattern(ref udtParseArg info, ref udtMultiParseArg extraInfo, ref udtCutByPatternArg patternInfo);
private static extern udtErrorCode udtCutDemoFileByTime(udtParserContextRef context, ref udtParseArg info, ref udtCutByTimeArg cutInfo, string demoFilePath);
private static extern udtErrorCode udtConvertDemoFiles(ref udtParseArg info, ref udtMultiParseArg extraInfo, ref udtProtocolConversionArg conversionInfo);