예제 #1
0
        private void RTPCExtractStrings(PropertyContainerFile rtpc)
        {
            var nodeQueue = new Queue <Node>();

            nodeQueue.Enqueue(rtpc.Root);

            while (nodeQueue.Count > 0)
            {
                var node = nodeQueue.Dequeue();

                AddHash(node.NameHash);

                foreach (var subs in node.Children)
                {
                    nodeQueue.Enqueue(subs);
                }
                foreach (var property in node.Properties)
                {
                    // uncomment to also put object ID / vec events keys and values in the hash list
                    //var hashes = property.Value.GetHashList();
                    //if (hashes != null)
                    //{
                    //    foreach (uint hash in hashes)
                    //        AddHash(hash);
                    //}

                    if (property.Value.Tag == "string")
                    {
                        AddString(property.Value.Compose(new Gibbed.ProjectData.HashList <uint>()));
                    }

                    AddHash(property.Key);
                }
            }
        }
예제 #2
0
        public static void Main(string[] args)
        {
            var    mode           = Mode.Unknown;
            Endian?endian         = null;
            bool   showHelp       = false;
            string currentProject = null;

            var options = new OptionSet
            {
                // ReSharper disable AccessToModifiedClosure
                { "e|export", "convert from binary to XML", v => SetOption(v, ref mode, Mode.Export) },
                { "i|import", "convert from XML to binary", v => SetOption(v, ref mode, Mode.Import) },
                { "l|little-endian", "write in little endian mode", v => SetOption(v, ref endian, Endian.Little) },
                { "b|big-endian", "write in big endian mode", v => SetOption(v, ref endian, Endian.Big) },
                // ReSharper restore AccessToModifiedClosure
                { "p|project=", "override current project", v => currentProject = v },
                { "h|help", "show this message and exit", v => showHelp = v != null },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (mode == Mode.Unknown && extras.Count >= 1)
            {
                var extension = Path.GetExtension(extras[0]);
                if (extension != null && extension.ToLowerInvariant() == ".xml")
                {
                    mode = Mode.Import;
                }
                else
                {
                    mode = Mode.Export;
                }
            }

            if (extras.Count < 1 || extras.Count > 2 ||
                showHelp == true ||
                mode == Mode.Unknown)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ [-e] input_bin [output_xml]", GetExecutableName());
                Console.WriteLine("       {0} [OPTIONS]+ [-i] input_xml [output_bin]", GetExecutableName());
                Console.WriteLine("Convert a property file between binary and XML format.");
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            var manager = ProjectData.Manager.Load(currentProject);

            if (manager.ActiveProject == null)
            {
                Console.WriteLine("Warning: no active project loaded.");
            }

            _Names = manager.LoadPropertyNames();

            if (mode == Mode.Export)
            {
                if (endian == null)
                {
                    endian = manager.GetSetting("endian", Endian.Little);
                }

                string inputPath  = extras[0];
                string outputPath = extras.Count > 1
                                        ? extras[1]
                                        : Path.ChangeExtension(inputPath, ".xml");

                var extension = Path.GetExtension(inputPath);

                IPropertyFile propertyFile;
                FileFormat    fileFormat;

                using (var input = File.OpenRead(inputPath))
                {
                    input.Seek(0, SeekOrigin.Begin);

                    if (PropertyContainerFile.CheckSignature(input) == true)
                    {
                        fileFormat = FileFormat.RTPC;

                        input.Seek(0, SeekOrigin.Begin);
                        var propertyContainerFile = new PropertyContainerFile();
                        propertyContainerFile.Deserialize(input);
                        endian       = propertyContainerFile.Endian;
                        propertyFile = propertyContainerFile;
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }

                var settings = new XmlWriterSettings
                {
                    Indent          = true,
                    IndentChars     = "\t",
                    CheckCharacters = false,
                };

                using (var output = File.Create(outputPath))
                    using (var writer = XmlWriter.Create(output, settings))
                    {
                        writer.WriteStartDocument();
                        writer.WriteStartElement("container");

                        if (extension != null)
                        {
                            writer.WriteAttributeString("extension", extension);
                        }

                        writer.WriteAttributeString("format", fileFormat.ToString());
                        writer.WriteAttributeString("endian", endian.Value.ToString());

                        if (propertyFile.Root != null)
                        {
                            writer.WriteStartElement("object");
                            WriteObject(writer, propertyFile.Root);
                            writer.WriteEndElement();
                        }

                        writer.WriteEndElement();
                        writer.WriteEndDocument();
                    }
            }
            else if (mode == Mode.Import)
            {
                string inputPath = extras[0];

                IPropertyFile propertyFile;
                string        extension;

                using (var input = File.OpenRead(inputPath))
                {
                    var doc = new XPathDocument(input);
                    var nav = doc.CreateNavigator();

                    var root = nav.SelectSingleNode("/container");
                    if (root == null)
                    {
                        throw new FormatException();
                    }

                    extension = root.GetAttribute("extension", "");
                    if (string.IsNullOrEmpty(extension) == true)
                    {
                        extension = ".bin";
                    }

                    FileFormat fileFormat;
                    var        formatAttribute = root.GetAttribute("format", "");
                    if (string.IsNullOrEmpty(formatAttribute) == false)
                    {
                        if (Enum.TryParse(formatAttribute, true, out fileFormat) == false)
                        {
                            throw new FormatException();
                        }
                    }
                    else
                    {
                        throw new FormatException();
                    }

                    var endianAttribute = root.GetAttribute("endian", "");
                    if (endian.HasValue == false &&
                        string.IsNullOrEmpty(endianAttribute) == false)
                    {
                        Endian fileEndian;
                        if (Enum.TryParse(endianAttribute, out fileEndian) == false)
                        {
                            throw new FormatException();
                        }

                        endian = fileEndian;
                    }
                    else
                    {
                        endian = manager.GetSetting("endian", Endian.Little);
                    }

                    switch (fileFormat)
                    {
                    case FileFormat.RTPC:
                    {
                        propertyFile = new PropertyContainerFile()
                        {
                            Endian = endian.Value,
                        };
                        break;
                    }

                    default:
                    {
                        throw new NotSupportedException();
                    }
                    }

                    var node = root.SelectSingleNode("object");
                    if (node != null)
                    {
                        propertyFile.Root = ParseObject(node);
                    }
                }

                string outputPath = extras.Count > 1
                                        ? extras[1]
                                        : Path.ChangeExtension(inputPath, extension);

                using (var output = File.Create(outputPath))
                {
                    propertyFile.Serialize(output);
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
        private void RTPCExtractStrings(PropertyContainerFile rtpc)
        {
            var nodeQueue = new Queue <Node>();

            nodeQueue.Enqueue(rtpc.Root);

            while (nodeQueue.Count > 0)
            {
                var node = nodeQueue.Dequeue();

                AddHash(node.NameHash, "identifiers");

                foreach (var subs in node.Children)
                {
                    nodeQueue.Enqueue(subs);
                }
                foreach (var property in node.Properties)
                {
                    var hashes = property.Value.GetHashList();

                    switch (property.Value.Tag)
                    {
                    case "vec_int":
                        if (hashes != null && hashes.Length > 0)
                        {
                            for (int i = 0; i < hashes.Length; ++i)
                            {
                                AddHash(hashes[i], "integer-values");
                            }
                        }
                        break;

                    case "int":
                        if (hashes != null && hashes.Length > 0)
                        {
                            AddHash(hashes[0], "integer-values");
                        }
                        break;

                    case "objectid":
                        if (hashes != null && hashes.Length > 0)
                        {
                            AddHash(hashes[0], "object-ids");
                            AddHash(hashes[1], "object-id-values");
                        }
                        break;

                    case "vec_events":
                        if (hashes != null && hashes.Length > 0)
                        {
                            for (int i = 0; i < hashes.Length; i += 2)
                            {
                                AddHash(hashes[i + 0], "events");
                                AddHash(hashes[i + 1], "event-values");
                            }
                        }
                        break;

                    case "string":
                        var str = property.Value.Compose(new Gibbed.ProjectData.HashList <uint>());
                        if (!string.IsNullOrEmpty(str))
                        {
                            AddString(str);
                            AddHash(str.HashJenkins(), "rtpc-strings");
                        }
                        break;
                    }

                    AddHash(property.Key, "identifiers");
                }
            }
        }
예제 #4
0
        private void HandleStream(Stream file, string type)
        {
            file.Position = 0;
            if (type == "ADF")
            {
                // Got some AAF file
                bool inc = false;
                try
                {
                    var adf = new AdfFile();
                    try
                    {
                        adf.Deserialize(file);
                        ++ADFReadCount;
                    }
                    catch
                    {
                        inc = true;
                        ++ADFSkipCount;
                    }
                    ADFExtractStrings(adf);
                }
                catch
                {
                    if (!inc)
                    {
                        ++ADFSkipCount;
                    }
                }
            }
            else if (type == "RTPC")
            {
                // Got some RTPC file
                try
                {
                    var propertyContainerFile = new PropertyContainerFile();
                    propertyContainerFile.Deserialize(file);
                    RTPCExtractStrings(propertyContainerFile);
                    ++RTPCReadCount;
                }
                catch
                {
                    ++RTPCSkipCount;
                }
            }
            else if (type == "AAF")
            {
                // Got some AAF Archive
                using (var cool = CreateCoolArchiveStream(file))
                {
                    var input = cool ?? file;

                    var smallArchive = new SmallArchiveFile();
                    smallArchive.Deserialize(input);

                    foreach (var entry in smallArchive.Entries)
                    {
                        this.AddString(entry.Name);
                        if (entry.Offset == 0)
                        {
                            continue;
                        }

                        ++this.FileCount;
                        this.PrintProgress();

                        input.Position = entry.Offset;
                        string subtype = this.GetType(input);
                        if (string.IsNullOrEmpty(subtype))
                        {
                            continue;
                        }
                        using (var entryStream = entry.ReadToMemoryStream(input))
                        {
                            this.HandleStream(entryStream, subtype);
                        }
                    }

                    ++this.AAFExtractCount;
                }
            }
        }
        private void HandleStream(Stream file, string type)
        {
            // flush if the limit is reached
            if (this._EntryCount > 300000)
            {
                this.flush();
            }

            //file.Position = 0;
            if (type == "ADF")
            {
                // Got some AAF file
                bool inc = false;
                try
                {
                    var adf = new AdfFile();
                    try
                    {
                        adf.Deserialize(file);
                        ++ADFReadCount;
                    }
                    catch
                    {
                        inc = true;
                        ++ADFSkipCount;
                    }
                    ADFExtractStrings(adf);
                }
                catch
                {
                    if (!inc)
                    {
                        ++ADFSkipCount;
                    }
                }
            }
            else if (type == "RTPC")
            {
                // Got some RTPC file
                try
                {
                    var propertyContainerFile = new PropertyContainerFile();
                    propertyContainerFile.Deserialize(file);
                    RTPCExtractStrings(propertyContainerFile);
                    ++RTPCReadCount;
                }
                catch
                {
                    ++RTPCSkipCount;
                }
            }
            else if (type == "AAF")
            {
                // Got some AAF Archive
                using (var cool = CreateCoolArchiveStream(file))
                {
                    var input = cool ?? file;

                    var smallArchive = new SmallArchiveFile();
                    smallArchive.Deserialize(input);

                    this._CurrentFile.Add(null);

                    foreach (var entry in smallArchive.Entries)
                    {
                        this.AddString(entry.Name);
                        if (entry.Offset == 0)
                        {
                            continue;
                        }

                        ++this.FileCount;
                        this.PrintProgress();

                        input.Position = entry.Offset;
                        string subtype = this.GetType(input);
                        if (string.IsNullOrEmpty(subtype))
                        {
                            continue;
                        }
                        // insert the name
                        this._CurrentFile[this._CurrentFile.Count - 1] = entry.Name;
                        this.UpdateCurrentFile();
                        // process the file
                        using (var entryStream = entry.ReadToMemoryStream(input))
                        {
                            // I know that this copies a copy of a memory (that's a stupid thing)
                            // but without this the memories goes crazy and if I force GC Collect
                            // that's even worse. So a little copy doesn't look bad in front of
                            // the horrors produced when you don't have it.
                            // to see what it's like, replace entryStream with input.
                            this.HandleStream(entryStream, subtype);
                        }
                    }

                    this._CurrentFile.RemoveAt(this._CurrentFile.Count - 1);

                    ++this.AAFExtractCount;
                }
            }
        }