public override bool Execute(List<string> args) { if (args.Count != 2) return false; var type = args[0]; var outDir = args[1]; TagLayoutWriter writer; switch (type) { case "csharp": writer = new CSharpLayoutWriter(); break; case "cpp": writer = new CppLayoutWriter(); break; default: return false; } Directory.CreateDirectory(outDir); var count = 0; using (var stream = _info.OpenCacheRead()) { foreach (var groupTag in _cache.Tags.NonNull().Select(t => t.Group.Tag).Distinct()) { TagLayoutGuess layout = null; TagInstance lastTag = null; foreach (var tag in _cache.Tags.FindAllInGroup(groupTag)) { Console.Write("Analyzing "); TagPrinter.PrintTagShort(tag); lastTag = tag; var analyzer = new TagAnalyzer(_cache); var data = _cache.ExtractTag(stream, tag); var tagLayout = analyzer.Analyze(data); if (layout != null) layout.Merge(tagLayout); else layout = tagLayout; } if (layout != null && lastTag != null) { Console.WriteLine("Writing {0} layout", groupTag); var name = _info.StringIds.GetString(lastTag.Group.Name); var tagLayout = LayoutGuessFinalizer.MakeLayout(layout, name, groupTag); var path = Path.Combine(outDir, writer.GetSuggestedFileName(tagLayout)); writer.WriteLayout(tagLayout, path); count++; } } } Console.WriteLine("Successfully generated {0} layouts!", count); return true; }
public override bool Execute(List<string> args) { if (args.Count != 3) return false; var inDir = args[0]; var type = args[1]; var outDir = args[2]; TagLayoutWriter writer; switch (type) { case "csharp": writer = new CSharpLayoutWriter(); break; case "cpp": writer = new CppLayoutWriter(); break; default: return false; } Directory.CreateDirectory(outDir); // For each tag whose tag group hasn't been processed yet, load its // plugin into a TagLayout and then write it using the layout // writer for the output type. We need an actual tag reference in // order to look up the group name without using a static table. var processedGroups = new HashSet<Tag>(); var numConflicts = 0; foreach (var tag in _cache.Tags.NonNull().Where(tag => !processedGroups.Contains(tag.Group.Tag))) { processedGroups.Add(tag.Group.Tag); // Get the plugin path and skip it if it doesn't exist var pluginFileName = SanitizeGroupTagName(tag.Group.Tag.ToString()) + ".xml"; var pluginPath = Path.Combine(inDir, pluginFileName); if (!File.Exists(pluginPath)) { Console.Error.WriteLine("WARNING: No plugin found for the '{0}' tag group", tag.Group.Tag); continue; } Console.WriteLine("Converting {0}...", pluginFileName); // Load the plugin into a layout AssemblyPluginLoadResults loadedPlugin; var groupName = _info.StringIds.GetString(tag.Group.Name); using (var reader = XmlReader.Create(pluginPath)) loadedPlugin = AssemblyPluginLoader.LoadPlugin(reader, groupName, tag.Group.Tag); // Warn the user about conflicts numConflicts += loadedPlugin.Conflicts.Count; foreach (var conflict in loadedPlugin.Conflicts) Console.WriteLine("WARNING: Field \"{0}\" at offset 0x{1:X} in block \"{2}\" conflicts!", conflict.Name, conflict.Offset, conflict.Block ?? "(root)"); // Write it var outPath = Path.Combine(outDir, writer.GetSuggestedFileName(loadedPlugin.Layout)); writer.WriteLayout(loadedPlugin.Layout, outPath); } Console.WriteLine("Successfully converted {0} plugins!", processedGroups.Count); if (numConflicts > 0) Console.WriteLine("However, {0} conflicts were found. You MUST fix these yourself!", numConflicts); return true; }