예제 #1
0
        public override bool Execute(List <string> args)
        {
            if (args.Count != 4)
            {
                return(false);
            }
            var srcTag = ArgumentParser.ParseTagIndex(_info, 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.ParseTagVersionMap(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
            DefinitionSet guessedVersion;

            destInfo.Version = Definition.Detect(destInfo.Cache, out guessedVersion);
            if (destInfo.Version == DefinitionSet.Unknown)
            {
                Console.WriteLine("Unrecognized target version!");
                return(true);
            }
            Console.WriteLine("- Detected version {0}", Definition.GetVersionString(destInfo.Version));

            if (_info.Version != DefinitionSet.HaloOnline498295 && destInfo.Version != DefinitionSet.HaloOnline106708)
            {
                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);

            // Load stringIDs
            Console.WriteLine("Loading the target string_ids.dat...");

            var resolver = StringIDResolverFactory.Create(destInfo.Version);

            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}", Definition.GetVersionString(_info.Version), Definition.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);
        }
예제 #2
0
        static void Main(string[] args)
        {
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.GetCultureInfo("en-US");
            ConsoleHistory.Initialize();

            // Get the file path from the first argument
            // If no argument is given, load tags.dat
            var filePath = (args.Length > 0) ? args[0] : "tags.dat";

            // If there are extra arguments, use them to automatically execute a command
            List <string> autoexecCommand = null;

            if (args.Length > 1)
            {
                autoexecCommand = args.Skip(1).ToList();
            }

            if (autoexecCommand == null)
            {
                Console.WriteLine("Tag Tool [{0}]", Assembly.GetExecutingAssembly().GetName().Version);
                Console.WriteLine();
                Console.WriteLine("Please report any bugs and feature requests at");
                Console.WriteLine("<https://github.com/camden-smallwood/TagTool/issues>.");
                Console.WriteLine();
                Console.Write("Reading tags...");
            }

            // Load the tag cache
            FileInfo fileInfo = null;
            TagCache cache    = null;

            try
            {
                fileInfo = new FileInfo(filePath);
                using (var stream = fileInfo.Open(FileMode.Open, FileAccess.Read))
                    cache = new TagCache(stream);
            }
            catch (Exception e)
            {
                Console.WriteLine("ERROR: " + e.Message);
                ConsoleHistory.Dump("hott_*_tags_init.log");
                return;
            }

            if (autoexecCommand == null)
            {
                Console.WriteLine("{0} tags loaded.", cache.Tags.Count);
            }

            // Version detection
            DefinitionSet closestVersion;
            var           version = Definition.Detect(cache, out closestVersion);

            if (version != DefinitionSet.Unknown)
            {
                if (autoexecCommand == null)
                {
                    var buildDate = DateTime.FromFileTime(cache.Timestamp);
                    Console.WriteLine("- Detected target engine version {0}.", Definition.GetVersionString(closestVersion));
                    Console.WriteLine("- This cache file was built on {0} at {1}.", buildDate.ToShortDateString(), buildDate.ToShortTimeString());
                }
            }
            else
            {
                Console.WriteLine("WARNING: The cache file's version was not recognized!");
                Console.WriteLine("Using the closest known version {0}.", Definition.GetVersionString(closestVersion));
                version = closestVersion;
            }

            // Load stringIDs
            Console.Write("Reading stringIDs...");
            var           stringIdPath = Path.Combine(fileInfo.DirectoryName ?? "", "string_ids.dat");
            var           resolver     = StringIDResolverFactory.Create(version);
            StringIDCache stringIds    = null;

            try
            {
                using (var stream = File.OpenRead(stringIdPath))
                    stringIds = new StringIDCache(stream, resolver);
            }
            catch (IOException)
            {
                Console.WriteLine("Warning: unable to open string_ids.dat!");
                Console.WriteLine("Commands which require stringID values will be unavailable.");
            }
            catch (Exception e)
            {
                Console.WriteLine("ERROR: " + e.Message);
                ConsoleHistory.Dump("hott_*_string_ids_init.log");
                return;
            }

            if (autoexecCommand == null && stringIds != null)
            {
                Console.WriteLine("{0} strings loaded.", stringIds.Strings.Count);
                Console.WriteLine();
            }

            var info = new OpenTagCache
            {
                Cache         = cache,
                CacheFile     = fileInfo,
                StringIDs     = stringIds,
                StringIDsFile = (stringIds != null) ? new FileInfo(stringIdPath) : null,
                Version       = version,
                Serializer    = new TagSerializer(version),
                Deserializer  = new TagDeserializer(version),
            };

            var tagNamesPath = "TagNames\\tagnames_" + Definition.GetVersionString(version) + ".csv";

            if (File.Exists(tagNamesPath))
            {
                using (var tagNamesStream = File.Open(tagNamesPath, FileMode.Open, FileAccess.Read))
                {
                    var reader = new StreamReader(tagNamesStream);

                    while (!reader.EndOfStream)
                    {
                        var line           = reader.ReadLine();
                        var separatorIndex = line.IndexOf(',');
                        var indexString    = line.Substring(2, separatorIndex - 2);

                        int tagIndex;
                        if (!int.TryParse(indexString, NumberStyles.HexNumber, null, out tagIndex))
                        {
                            tagIndex = -1;
                        }

                        if (tagIndex < 0 || tagIndex >= cache.Tags.Count)
                        {
                            continue;
                        }

                        var nameString = line.Substring(separatorIndex + 1);

                        if (nameString.Contains(" "))
                        {
                            var lastSpaceIndex = nameString.LastIndexOf(' ');
                            nameString = nameString.Substring(lastSpaceIndex + 1, nameString.Length - lastSpaceIndex - 1);
                        }

                        info.TagNames[tagIndex] = nameString;
                    }

                    reader.Close();
                }
            }

            foreach (var tag in info.Cache.Tags)
            {
                if (tag != null && !info.TagNames.ContainsKey(tag.Index))
                {
                    info.TagNames[tag.Index] = $"0x{tag.Index:X4}";
                }
            }

            // Create command context
            var contextStack = new CommandContextStack();
            var tagsContext  = TagCacheContextFactory.Create(contextStack, info);

            contextStack.Push(tagsContext);

            // If autoexecuting a command, just run it and return
            if (autoexecCommand != null)
            {
                if (!ExecuteCommand(contextStack.Context, autoexecCommand))
                {
                    Console.WriteLine("Unrecognized command: {0}", autoexecCommand[0]);
                }
                return;
            }

            Console.WriteLine("Enter \"help\" to list available commands. Enter \"exit\" to quit.");
            while (true)
            {
                // Read and parse a command
                Console.WriteLine();
                Console.Write("{0}> ", contextStack.GetPath());
                var commandLine = Console.ReadLine();
                if (commandLine == null)
                {
                    break;
                }
                string redirectFile;
                var    commandArgs = ArgumentParser.ParseCommand(commandLine, out redirectFile);
                if (commandArgs.Count == 0)
                {
                    continue;
                }

                // If "exit" or "quit" is given, pop the current context
                if (commandArgs[0] == "exit" || commandArgs[0] == "quit")
                {
                    if (!contextStack.Pop())
                    {
                        break; // No more contexts - quit
                    }
                    continue;
                }

                // Handle redirection
                var          oldOut         = Console.Out;
                StreamWriter redirectWriter = null;
                if (redirectFile != null)
                {
                    redirectWriter = new StreamWriter(File.Open(redirectFile, FileMode.Create, FileAccess.Write));
                    Console.SetOut(redirectWriter);
                }

                // Try to execute it
                if (!ExecuteCommand(contextStack.Context, commandArgs))
                {
                    Console.WriteLine("Unrecognized command: {0}", commandArgs[0]);
                    Console.WriteLine("Use \"help\" to list available commands.");
                }

                // Undo redirection
                if (redirectFile != null)
                {
                    Console.SetOut(oldOut);
                    redirectWriter.Dispose();
                    Console.WriteLine("Wrote output to {0}.", redirectFile);
                }
            }
        }