Пример #1
0
 public GetDepModels(OpenTagCache info)
     : base(CommandFlags.None,
     "getdepmodels",
     "Extracts the render models of gameobjects referenced by a map.",
     "getdepmodels <map-file-path> <output-dir-path>",
     "Extract the render models of all game-objects referenced by a map." +
     "The map-file-path arg must be of an existing map (i.e in HaloOnline\\maps\\)")
 {
     _info = info;
 }
Пример #2
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);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Creates a CollisionModel bsp from a Scenario StructureBsp.
        /// This does not work for sbsps with > 65536 planes, which use a
        ///  larger encoding for their bsp related structs differing from the
        ///  struct used in common with collision model bsps.
        /// </summary>
        /// <returns></returns>
        public static BSP fromSbsp(ScenarioStructureBsp sbsp, OpenTagCache info)
        {
            // Need to work out how to do that class attribute enumeration thing
            // so all of this folds down to < 10 lines
            BSP bsp = fromSbspInit(sbsp);
            var resource = sbsp.Resource3;
            var resourceManager = new ResourceDataManager();
            try
            {
                resourceManager.LoadCachesFromDirectory(info.CacheFile.DirectoryName);
            }
            catch
            {
                Console.WriteLine("Unable to load the resource .dat files.");
                Console.WriteLine("Make sure that they all exist and are valid.");
            }

            //Create a binary reader for the resource
            Stream stream = new MemoryStream();
            resourceManager.Extract(sbsp.Resource3, stream);
            BinaryReader reader = new BinaryReader(stream);
            reader.BaseStream.Position = 0;
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Bsp3dNodes.Count; ++i)
            {
                BSP.Bsp3dNode node = new BSP.Bsp3dNode();
                node.Plane = reader.ReadInt16();
                node.BackChildLower = reader.ReadByte();
                node.BackChildMid = reader.ReadByte();
                node.BackChildUpper = reader.ReadByte();
                node.FrontChildLower = reader.ReadByte();
                node.FrontChildMid = reader.ReadByte();
                node.FrontChildUpper = reader.ReadByte();
                bsp.Bsp3dNodes[i] = node;
            }

            //Align to the next multiple of 16
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Planes.Count; ++i)
            {
                BSP.Plane plane = new BSP.Plane();
                plane.PlaneI = reader.ReadSingle();
                plane.PlaneJ = reader.ReadSingle();
                plane.PlaneK = reader.ReadSingle();
                plane.PlaneD = reader.ReadSingle();
                bsp.Planes[i] = plane;
            }

            //Put here for consistency
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Leaves.Count; ++i)
            {
                BSP.Leaf leaf = new BSP.Leaf();
                leaf.Flags = reader.ReadInt16();
                leaf.Bsp2dReferenceCount = reader.ReadInt16();
                leaf.Unknown = reader.ReadInt16();
                leaf.FirstBsp2dReference = reader.ReadInt16();
                bsp.Leaves[i] = leaf;
            }

            //Align to the next multiple of 16
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Bsp2dReferences.Count; ++i)
            {
                BSP.Bsp2dReference bsp2dref = new BSP.Bsp2dReference();
                bsp2dref.Plane = reader.ReadInt16();
                bsp2dref.Bsp2dNode = reader.ReadInt16();
                bsp.Bsp2dReferences[i] = bsp2dref;
            }

            //Align to the next multiple of 16
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Bsp2dNodes.Count; ++i)
            {
                BSP.Bsp2dNode node = new BSP.Bsp2dNode();
                node.PlaneI = reader.ReadSingle();
                node.PlaneJ = reader.ReadSingle();
                node.PlaneD = reader.ReadSingle();
                node.LeftChild = reader.ReadInt16();
                node.RightChild = reader.ReadInt16();
                bsp.Bsp2dNodes[i] = node;
            }

            //Put here for consistency
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Surfaces.Count; ++i)
            {
                BSP.Surface surface = new BSP.Surface();
                surface.Plane = reader.ReadUInt16();
                surface.FirstEdge = reader.ReadUInt16();
                surface.Material = reader.ReadInt16();
                surface.Unknown = reader.ReadInt16();
                surface.BreakableSurface = reader.ReadInt16();
                surface.Unknown2 = reader.ReadInt16();
                bsp.Surfaces[i] = surface;
            }

            //Align to the next multiple of 16
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Edges.Count; ++i)
            {
                BSP.Edge edge = new BSP.Edge();
                edge.StartVertex = reader.ReadUInt16();
                edge.EndVertex = reader.ReadUInt16();
                edge.ForwardEdge = reader.ReadUInt16();
                edge.ReverseEdge = reader.ReadUInt16();
                edge.LeftSurface = reader.ReadUInt16();
                edge.RightSurface = reader.ReadUInt16();
                bsp.Edges[i] = edge;
            }

            //Align to the next multiple of 16
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Vertices.Count; ++i)
            {
                BSP.Vertex vert = new BSP.Vertex();
                vert.PointX = reader.ReadSingle();
                vert.PointY = reader.ReadSingle();
                vert.PointZ = reader.ReadSingle();
                vert.FirstEdge = reader.ReadInt16();
                vert.Unknown = reader.ReadInt16();
                bsp.Vertices[i] = vert;
            }

            return bsp;
        }