示例#1
0
 /// <summary>
 /// Creates a stringID resolver for a given engine version.
 /// </summary>
 /// <param name="version">The version.</param>
 /// <returns>The resolver.</returns>
 public static StringIdResolverBase Create(EngineVersion version)
 {
     if (VersionDetection.Compare(version, EngineVersion.V12_1_700123_cert_ms30_oct19) >= 0)
     {
         return(new V12_1_700123.StringIdResolver());
     }
     if (VersionDetection.Compare(version, EngineVersion.V11_1_498295_Live) >= 0)
     {
         return(new V11_1_498295.StringIdResolver());
     }
     return(new V1_106708.StringIdResolver());
 }
示例#2
0
        /// <summary>
        /// Writes the map out to a CSV.
        /// </summary>
        /// <param name="writer">The writer to write to.</param>
        public void WriteCsv(TextWriter writer)
        {
            // Write a list of versions being represented
            writer.WriteLine(string.Join(",", _versionMaps.Keys.Select(VersionDetection.GetVersionString)));

            // Write a list of timestamps for the versions
            writer.WriteLine(string.Join(",", _versionMaps.Keys.Select(v => VersionDetection.GetTimestamp(v).ToString("X16"))));

            // Now write out each tag
            for (var i = 0; i < _nextGlobalTagIndex; i++)
            {
                var globalIndex = i;
                writer.WriteLine(string.Join(",", _versionMaps.Keys.Select(v => _versionMaps[v].GetVersionedTagIndex(globalIndex).ToString("X4"))));
            }
        }
示例#3
0
        /// <summary>
        /// Parses a map from a CSV.
        /// </summary>
        /// <param name="reader">The reader to read from.</param>
        /// <returns>The map that was read.</returns>
        public static TagVersionMap ParseCsv(TextReader reader)
        {
            var result = new TagVersionMap();

            // Skip the first line, we don't need it
            if (reader.ReadLine() == null)
            {
                return(result);
            }

            // Read the timestamp list and resolve each one
            var timestampLine = reader.ReadLine();

            if (timestampLine == null)
            {
                return(result);
            }
            var timestamps = timestampLine.Split(',').Select(t =>
            {
                long r;
                if (long.TryParse(t, NumberStyles.HexNumber, null, out r))
                {
                    return(r);
                }
                return(-1);
            });
            var versions = timestamps.Select(t =>
            {
                EngineVersion closest;
                return(VersionDetection.DetectVersionFromTimestamp(t, out closest));
            }).ToArray();

            // Read each line and store the tag indexes in the result map
            while (true)
            {
                var line = reader.ReadLine();
                if (line == null)
                {
                    break;
                }
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                // Parse each tag index as a hex number
                var tags       = line.Split(',');
                var tagIndexes = tags.Select(t =>
                {
                    int r;
                    if (int.TryParse(t, NumberStyles.HexNumber, null, out r))
                    {
                        return(r);
                    }
                    return(-1);
                }).ToArray();

                // Now connect all of them to the first tag
                for (var i = 1; i < tagIndexes.Length; i++)
                {
                    if (tagIndexes[i] >= 0)
                    {
                        result.Add(versions[0], tagIndexes[0], versions[i], tagIndexes[i]);
                    }
                }
            }
            return(result);
        }
示例#4
0
        static void Main(string[] args)
        {
            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("Halo Online Tag Tool [{0}]", Assembly.GetExecutingAssembly().GetName().Version);
                Console.WriteLine();
                Console.WriteLine("Please report any bugs and feature requests at");
                Console.WriteLine("<https://github.com/ElDewrito/HaloOnlineTagTool/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
            EngineVersion closestVersion;
            var           version = VersionDetection.DetectVersion(cache, out closestVersion);

            if (version != EngineVersion.Unknown)
            {
                if (autoexecCommand == null)
                {
                    var buildDate = DateTime.FromFileTime(cache.Timestamp);
                    Console.WriteLine("- Detected target engine version {0}.", VersionDetection.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}.", VersionDetection.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),
            };

            // 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);
                }
            }
        }