Beispiel #1
0
        /// <summary>
        /// Reads a Game Maker tree node recursively
        /// </summary>
        private static void ReadNodeRecursive(GMNode parent, GMFileReader reader)
        {
            // Iterate through child nodes
            foreach (GMNode node in parent.Nodes)
            {
                // Read node data
                node.NodeType     = (GMNodeType)(reader.ReadGMInt());
                node.ResourceType = (GMResourceType)(reader.ReadGMInt());
                node.Id           = reader.ReadGMInt();
                node.Name         = reader.ReadGMString();
                node.Children     = reader.ReadGMInt();

                // If the node has child nodes
                if (node.Children > 0)
                {
                    // Create a new node array
                    node.Nodes = new GMNode[node.Children];

                    // Iterate through children
                    for (int i = 0; i < node.Children; i++)
                    {
                        // Add new node
                        node.Nodes[i] = new GMNode();
                    }

                    // Read in child nodes recursively
                    ReadNodeRecursive(node, reader);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Reads nodes recursively
        /// </summary>
        /// <param name="xmlNode">The current xml node</param>
        /// <param name="gmNode">The current Game Maker node</param>
        /// <param name="type">The current resource type</param>
        /// <param name="assets">The asset list to add any assets to</param>
        private static void ReadNodeGMX(XmlNode xmlNode, GMNode gmNode, GMResourceType type, List <string> assets)
        {
            // If not a valid node, continue
            if (!IsValidXmlNode(xmlNode))
            {
                return;
            }

            // Read node data
            gmNode.NodeType        = GetNodeType(xmlNode);
            gmNode.ResourceType    = gmNode.NodeType == GMNodeType.Parent ? GetResourceType(xmlNode.Name) : type;
            gmNode.ResourceSubType = gmNode.NodeType == GMNodeType.Child && gmNode.ResourceType == GMResourceType.DataFiles ? GMResourceSubType.DataFile : GetResourceSubType(xmlNode.ParentNode.Name);
            gmNode.FilePath        = gmNode.NodeType == GMNodeType.Child ? gmNode.ResourceSubType == GMResourceSubType.DataFile ? xmlNode.ParentNode.ParentNode.ParentNode.Attributes["name"].Value : xmlNode.Value : "";
            gmNode.Name            = GetNodeName(xmlNode, gmNode);
            gmNode.Id       = gmNode.NodeType == GMNodeType.Child ? GetIdFromName(gmNode.Name) : -1;
            gmNode.Children = xmlNode.HasChildNodes ? xmlNode.ChildNodes.Count : 0;
            gmNode.Nodes    = gmNode.Children == 0 ? null : new GMNode[gmNode.Children];

            // If the node is a child and a major game resource, add to asset list
            if (gmNode.NodeType == GMNodeType.Child && gmNode.ResourceSubType != GMResourceSubType.None)
            {
                assets.Add(gmNode.Name);
            }

            // If there are no children, return
            if (gmNode.Children == 0)
            {
                return;
            }

            // Iterate through children
            for (int i = 0; i < gmNode.Children; i++)
            {
                gmNode.Nodes[i] = new GMNode();
                GMResourceSubType sub = GetResourceSubType(xmlNode.ChildNodes[i].Name);

                // If the next node is a resource subtype node, skip it and just get its text value, else read as usual
                if (sub != GMResourceSubType.None)
                {
                    // If not a constant get standard attributes
                    gmNode.Nodes[i].Tag = GetChildNodeAttribute(xmlNode.ChildNodes[i], gmNode);

                    if (sub == GMResourceSubType.DataFile)
                    {
                        ReadNodeGMX(xmlNode.ChildNodes[i].ChildNodes[0].ChildNodes[0], gmNode.Nodes[i], gmNode.ResourceType, assets);
                    }
                    else
                    {
                        ReadNodeGMX(xmlNode.ChildNodes[i].ChildNodes[0], gmNode.Nodes[i], gmNode.ResourceType, assets);
                    }
                }
                else
                {
                    ReadNodeGMX(xmlNode.ChildNodes[i], gmNode.Nodes[i], gmNode.ResourceType, assets);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Gets the name for the GMNode based on node type
        /// </summary>
        /// <param name="xmlNode">The xml node to extract the name from</param>
        /// <param name="gmNode">The Game Maker node to determine how to extract the name</param>
        /// <returns></returns>
        private static string GetNodeName(XmlNode xmlNode, GMNode gmNode)
        {
            // Get the node name based on node type
            switch (gmNode.NodeType)
            {
            case GMNodeType.Child: return(gmNode.ResourceType == GMResourceType.Constants ? xmlNode.ParentNode.Attributes[0].Value :
                                          xmlNode.Value.Substring(xmlNode.Value.LastIndexOf("\\") + 1));;

            case GMNodeType.Group: return(xmlNode.Attributes.Count > 0 ?
                                          xmlNode.Attributes.Count > 0 && gmNode.ResourceType == GMResourceType.DataFiles ?
                                          xmlNode.Attributes[1].Value : xmlNode.Attributes[0].Value : xmlNode.Name);

            default: return(xmlNode.Name);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Gets the given resource type's project node
        /// </summary>
        /// <param name="file">The path to the project file</param>
        /// <param name="type">The resource type to search for</param>
        /// <returns>A node of the resource type</returns>
        public static GMNode ReadTreeNodeGMX(string file, GMResourceType type)
        {
            // Get all the project nodes
            Dictionary <string, string> assets = new Dictionary <string, string>();
            GMNode parent = ReadTreeGMX(file);

            // Iterate through nodes till we find the desired type
            foreach (GMNode node in parent.Nodes)
            {
                if (node.ResourceType == type)
                {
                    return(node);
                }
            }

            // The resource type could not be found
            return(null);
        }
Beispiel #5
0
 /// <summary>
 /// For now gets the first attribute node of a child node, if one exists
 /// This is for child nodes like shaders and extensions
 /// </summary>
 /// <param name="xmlNode">The xml node to check</param>
 /// <returns></returns>
 private static object GetChildNodeAttribute(XmlNode xmlNode, GMNode gmNode)
 {
     // If the child node has an attribute
     if (xmlNode.Attributes != null && xmlNode.Attributes.Count > 0)
     {
         if (gmNode.ResourceType == GMResourceType.Constants)
         {
             return(new KeyValuePair <string, string>(xmlNode.Attributes[0].Value, xmlNode.ChildNodes[0].Value));
         }
         else
         {
             return(new KeyValuePair <string, string>(xmlNode.Attributes[0].Name, xmlNode.Attributes[0].Value));
         }
     }
     else
     {
         return(null);
     }
 }
Beispiel #6
0
        /// <summary>
        /// Reads a project tree from a GMX project file
        /// </summary>
        /// <param name="file">Path to the project file</param>
        /// <returns>A root project node</returns>
        public static GMNode ReadTreeGMX(string file)
        {
            try
            {
                // Set the asset list
                List <string> assets = new List <string>();

                // Create the project node
                GMNode root = new GMNode();

                // Create an xml document from the file
                XmlDocument document = new XmlDocument();
                document.Load(file);

                // Iterate through child nodes
                foreach (XmlNode node in document.ChildNodes)
                {
                    // If not a valid node, continue
                    if (!IsValidXmlNode(node))
                    {
                        continue;
                    }

                    // Read the child nodes
                    ReadNodeGMX(node, root, GMResourceType.None, assets);
                }

                // Return the project node
                root.Name     = Path.GetFileNameWithoutExtension(file);
                root.NodeType = GMNodeType.Root;
                root.Tag      = assets;
                return(root);
            }
            catch (Exception)
            {
                throw new Exception("There was a problem reading the project file. The project file may be corrupt, or it may be an updated version that isn't supported.");
            }
        }
Beispiel #7
0
        /// <summary>
        /// Writes object XML recursively
        /// </summary>
        /// <param name="xmlNode">The given xml node</param>
        /// <param name="node">The given GM node to set up</param>
        /// <param name="project">Project reference</param>
        private static void WriteNodeGMX(XmlTextWriter writer, GMNode node, ref GMProject project)
        {
            // If a child, write out value and return
            if (node.NodeType == GMNodeType.Child)
            {
                // If the child has an attribute or attributes
                if (node.Tag != null)
                {
                    // Get the attribute key and value
                    KeyValuePair <string, string> attribute = (KeyValuePair <string, string>)node.Tag;

                    // If a constant, use the name attribute and the constant name key, else use dattribute
                    if (node.ResourceType == GMResourceType.Constants)
                    {
                        XMLWriteFullElement(writer, GMXEnumString(node.ResourceSubType), node.FilePath,
                                            "name", attribute.Key);
                    }
                    else
                    {
                        XMLWriteFullElement(writer, GMXEnumString(node.ResourceSubType), node.FilePath,
                                            attribute.Key, attribute.Value);
                    }
                }
                else
                {
                    // If the child is a datafile, write out properties, else write standard
                    if (node.ResourceSubType == GMResourceSubType.DataFile)
                    {
                        // Get the data file instance
                        GMDataFile dataFile = project.DataFiles.Find(d => d.Id == node.Id && d.Group == node.FilePath);

                        // If the datafile was not found, return
                        if (dataFile == null)
                        {
                            return;
                        }

                        // Write the data file
                        writer.WriteStartElement(GMXEnumString(GMResourceSubType.DataFile));
                        XMLWriteFullElement(writer, GMXEnumString(GMXDataFileProperty.Name), dataFile.Name);
                        XMLWriteFullElement(writer, GMXEnumString(GMXDataFileProperty.Exists), GetGMXBool(dataFile.Exists));
                        XMLWriteFullElement(writer, GMXEnumString(GMXDataFileProperty.Size), dataFile.Size.ToString());
                        XMLWriteFullElement(writer, GMXEnumString(GMXDataFileProperty.ExportAction), dataFile.ExportAction.ToString());
                        XMLWriteFullElement(writer, GMXEnumString(GMXDataFileProperty.ExportDir), dataFile.ExportDirectory);
                        XMLWriteFullElement(writer, GMXEnumString(GMXDataFileProperty.Overwrite), GetGMXBool(dataFile.OverwriteFile));
                        XMLWriteFullElement(writer, GMXEnumString(GMXDataFileProperty.FreeData), GetGMXBool(dataFile.FreeDataMemory));
                        XMLWriteFullElement(writer, GMXEnumString(GMXDataFileProperty.RemoveEnd), GetGMXBool(dataFile.RemoveAtGameEnd));
                        XMLWriteFullElement(writer, GMXEnumString(GMXDataFileProperty.Store), GetGMXBool(dataFile.Store));

                        // Write the configs for the datafile
                        writer.WriteStartElement(GMXEnumString(GMResourceType.ConfigOptions));
                        foreach (GMConfig config in dataFile.Configs)
                        {
                            writer.WriteStartElement(GMXEnumString(GMResourceSubType.Config));
                            writer.WriteAttributeString(GMXEnumString(GMXDataFileProperty.Name), config.Name);
                            XMLWriteFullElement(writer, GMXEnumString(GMXConfigProperty.CopyToMask), config.CopyToMask.ToString());
                            writer.WriteEndElement();
                        }
                        writer.WriteEndElement();

                        // Finish writing the datafile
                        XMLWriteFullElement(writer, GMXEnumString(GMXDataFileProperty.Filename), dataFile.FileName);
                        writer.WriteEndElement();
                    }
                    else
                    {
                        XMLWriteFullElement(writer, GMXEnumString(node.ResourceSubType), node.FilePath);
                    }
                }
                return;
            }

            // Start writing the parent element
            writer.WriteStartElement(GMXEnumString(node.ResourceType));

            // If not a parent node and has no attribute name, write the name attribute
            if (!(node.NodeType == GMNodeType.Parent && !HasNameAttribute(node.ResourceType)))
            {
                // If a constant node, write the number instead of the name
                if (node.ResourceType == GMResourceType.Constants)
                {
                    writer.WriteAttributeString("number", node.Nodes.Length.ToString());
                }
                // If a datafile node, write the number and name attributes
                else if (node.ResourceType == GMResourceType.DataFiles)
                {
                    writer.WriteAttributeString("number", project.LastDataFileId.ToString());
                    writer.WriteAttributeString("name", node.Name);
                }
                // Just write the name
                else
                {
                    writer.WriteAttributeString("name", node.NodeType == GMNodeType.Group ? node.Name : GetParentName(node.ResourceType));
                }
            }

            // If the node has children
            if (node.Nodes != null && node.Nodes.Length > 0)
            {
                // Write all children
                for (int i = 0; i < node.Nodes.Length; i++)
                {
                    WriteNodeGMX(writer, node.Nodes[i], ref project);
                }
            }

            // End writing the parent element
            writer.WriteEndElement();
        }
Beispiel #8
0
        /// <summary>
        /// Reads an object Tree from a GM file reader stream
        /// </summary>
        public static GMNode ReadTree(string name, GMFileReader reader)
        {
            // Get version
            int version = reader.ReadGMInt();

            // Check version
            if (version != 500 && version != 540 && version != 700)
            {
                throw new Exception("Unsupported Project Tree object version.");
            }

            // Room execution Order
            reader.ReadGMBytes(reader.ReadGMInt() * 4);

            // Set the number of main resource nodes
            int rootNum = (version > 540) ? 12 : 11;

            // Create a project node
            GMNode projectTree = new GMNode();

            projectTree.Nodes    = new GMNode[rootNum];
            projectTree.Name     = name;
            projectTree.NodeType = GMNodeType.Parent;
            projectTree.Children = projectTree.Nodes.Length;

            // Iterate through Game Maker project root nodes
            for (int i = 0; i < rootNum; i++)
            {
                // Create new node
                GMNode node = new GMNode();

                // Read node data
                node.NodeType     = (GMNodeType)(reader.ReadGMInt());
                node.ResourceType = (GMResourceType)(reader.ReadGMInt());
                node.Id           = reader.ReadGMInt();
                node.Name         = reader.ReadGMString();
                node.Children     = reader.ReadGMInt();

                // If there is at least one child node
                if (node.Children > 0)
                {
                    // Create a new node array
                    node.Nodes = new GMNode[node.Children];

                    // Iterate through children
                    for (int j = 0; j < node.Children; j++)
                    {
                        // Add new node
                        node.Nodes[j] = new GMNode();
                    }

                    // Read in child nodes recursively
                    ReadNodeRecursive(node, reader);
                }

                // Add new main node
                projectTree.Nodes[i] = node;
            }

            // Return project tree
            return(projectTree);
        }