public override bool Execute(List <string> args) { if (args.Count < 2) { return(false); } var outputPath = args[0]; // Load each file and do version detection var infos = new List <OpenTagCache>(); foreach (var path in args.Skip(1)) { Console.WriteLine("Loading {0}...", path); // Load the cache file var info = new OpenTagCache { CacheFile = new FileInfo(path) }; using (var stream = info.OpenCacheRead()) info.Cache = new TagCache(stream); // Do version detection, and don't accept the closest version // because that might not work EngineVersion closestVersion; info.Version = VersionDetection.DetectVersion(info.Cache, out closestVersion); if (info.Version == EngineVersion.Unknown) { Console.WriteLine("- Unrecognized version! Ignoring."); continue; } info.Deserializer = new TagDeserializer(info.Version); infos.Add(info); } var result = new TagVersionMap(); using (var baseStream = _info.OpenCacheRead()) { // Get the scenario tags for this cache Console.WriteLine("Finding base scenario tags..."); var baseScenarios = FindScenarios(_info, baseStream); var baseVersion = _info.Version; var baseTagData = new Dictionary <int, object>(); foreach (var scenario in baseScenarios) { baseTagData[scenario.Tag.Index] = scenario.Data; } // Now compare with each of the other caches foreach (var info in infos) { using (var stream = info.OpenCacheRead()) { Console.WriteLine("Finding scenario tags in {0}...", info.CacheFile.FullName); // Get the scenario tags and connect them to the base tags var scenarios = FindScenarios(info, stream); var tagsToCompare = new Queue <QueuedTag>(); for (var i = 0; i < scenarios.Count; i++) { tagsToCompare.Enqueue(scenarios[i]); if (i < baseScenarios.Count) { result.Add(baseVersion, baseScenarios[i].Tag.Index, info.Version, scenarios[i].Tag.Index); } } // Process each tag in the queue, enqueuing all of its dependencies as well while (tagsToCompare.Count > 0) { // Get the tag and its data var tag = tagsToCompare.Dequeue(); TagPrinter.PrintTagShort(tag.Tag); var data = tag.Data; if (data == null) { // No data yet - deserialize it var context = new TagSerializationContext(stream, info.Cache, info.StringIds, tag.Tag); var type = TagStructureTypes.FindByGroupTag(tag.Tag.Group.Tag); data = info.Deserializer.Deserialize(context, type); } // Now get the data for the base tag var baseTag = result.Translate(info.Version, tag.Tag.Index, baseVersion); if (baseTag == -1 || _info.Cache.Tags[baseTag].Group.Tag != tag.Tag.Group.Tag) { continue; } object baseData; if (!baseTagData.TryGetValue(baseTag, out baseData)) { // No data yet - deserialize it var context = new TagSerializationContext(baseStream, _info.Cache, _info.StringIds, _info.Cache.Tags[baseTag]); var type = TagStructureTypes.FindByGroupTag(tag.Tag.Group.Tag); baseData = _info.Deserializer.Deserialize(context, type); baseTagData[baseTag] = baseData; } // Compare the two blocks CompareBlocks(baseData, baseVersion, data, info.Version, result, tagsToCompare); } } } } // Write out the CSV Console.WriteLine("Writing results..."); using (var writer = new StreamWriter(File.Open(outputPath, FileMode.Create, FileAccess.Write))) result.WriteCsv(writer); Console.WriteLine("Done!"); return(true); }
public override bool Execute(List <string> args) { if (args.Count != 4) { return(false); } var srcTag = ArgumentParser.ParseTagIndex(_info.Cache, args[0]); if (srcTag == null) { return(false); } var csvPath = args[1]; var csvOutPath = args[2]; var targetDir = args[3]; // Load the CSV Console.WriteLine("Reading {0}...", csvPath); TagVersionMap tagMap; using (var reader = new StreamReader(File.OpenRead(csvPath))) tagMap = TagVersionMap.ParseCsv(reader); // Load destination files Console.WriteLine("Loading the target tags.dat..."); var destCachePath = Path.Combine(targetDir, "tags.dat"); var destInfo = new OpenTagCache { CacheFile = new FileInfo(destCachePath) }; using (var stream = destInfo.OpenCacheRead()) destInfo.Cache = new TagCache(stream); // Do version detection EngineVersion guessedVersion; destInfo.Version = VersionDetection.DetectVersion(destInfo.Cache, out guessedVersion); if (destInfo.Version == EngineVersion.Unknown) { Console.WriteLine("Unrecognized target version!"); return(true); } Console.WriteLine("- Detected version {0}", VersionDetection.GetVersionString(destInfo.Version)); if (_info.Version != EngineVersion.V11_1_498295_Live && destInfo.Version != EngineVersion.V1_106708_cert_ms23) { Console.Error.WriteLine("Conversion is only supported from 11.1.498295 Live to 1.106708 cert_ms23."); return(true); } // Set up version-specific objects destInfo.Serializer = new TagSerializer(destInfo.Version); destInfo.Deserializer = new TagDeserializer(destInfo.Version); StringIdResolverBase resolver; if (VersionDetection.Compare(destInfo.Version, EngineVersion.V11_1_498295_Live) >= 0) { resolver = new V11_1_498295.StringIdResolver(); } else { resolver = new V1_106708.StringIdResolver(); } // Load stringIDs Console.WriteLine("Loading the target string_ids.dat..."); var destStringIdsPath = Path.Combine(targetDir, "string_ids.dat"); destInfo.StringIdsFile = new FileInfo(destStringIdsPath); using (var stream = destInfo.StringIdsFile.OpenRead()) destInfo.StringIds = new StringIdCache(stream, resolver); // Load resources for the target build Console.WriteLine("Loading target resources..."); var destResources = new ResourceDataManager(); destResources.LoadCachesFromDirectory(destInfo.CacheFile.DirectoryName); // Load resources for our build Console.WriteLine("Loading source resources..."); var srcResources = new ResourceDataManager(); srcResources.LoadCachesFromDirectory(_info.CacheFile.DirectoryName); Console.WriteLine(); Console.WriteLine("CONVERTING FROM VERSION {0} TO {1}", VersionDetection.GetVersionString(_info.Version), VersionDetection.GetVersionString(destInfo.Version)); Console.WriteLine(); TagInstance resultTag; using (Stream srcStream = _info.OpenCacheRead(), destStream = destInfo.OpenCacheReadWrite()) resultTag = ConvertTag(srcTag, _info, srcStream, srcResources, destInfo, destStream, destResources, tagMap); Console.WriteLine(); Console.WriteLine("Repairing decal systems..."); FixDecalSystems(destInfo, resultTag.Index); Console.WriteLine(); Console.WriteLine("Saving stringIDs..."); using (var stream = destInfo.StringIdsFile.Open(FileMode.Open, FileAccess.ReadWrite)) destInfo.StringIds.Save(stream); Console.WriteLine("Writing {0}...", csvOutPath); using (var stream = new StreamWriter(File.Open(csvOutPath, FileMode.Create, FileAccess.ReadWrite))) tagMap.WriteCsv(stream); // Uncomment this to add the new tag as a dependency to cfgt to make testing easier /*using (var stream = destInfo.OpenCacheReadWrite()) * { * destInfo.Cache.Tags[0].Dependencies.Add(resultTag.Index); * destInfo.Cache.UpdateTag(stream, destInfo.Cache.Tags[0]); * }*/ Console.WriteLine(); Console.WriteLine("All done! The converted tag is:"); TagPrinter.PrintTagShort(resultTag); return(true); }