Пример #1
0
        static void HandleImportMetaOptions(string[] args)
        {
            CommandLine.Parse <ImportMetaOptions>(args, (opts, gOpts) =>
            {
                if (opts.Metadata)
                {
                    Init(args);
                }
                else
                {
                    EnsurePath();
                    EnsureKeys();
                    EnsureCache();
                }

                if (opts.InputFiles == null)
                {
                    Console.WriteLine("Please provide input files with -i --input");
                    return;
                }
                else
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        Console.WriteLine(fileInfo.FullName);

                        var strings = MetaUtilities.GetAllStringsFromXml(fileInfo.FullName);

                        foreach (var str in strings)
                        {
                            Utils.Hash(str.ToLowerInvariant());
                        }

                        var doc = new XmlDocument();

                        doc.Load(fileInfo.FullName);

                        var res          = new ResourceFile_GTA5_pc <MetaFile>();
                        res.Version      = 2;
                        res.ResourceData = XmlMeta.GetMeta(doc);

                        if (fileInfo.Name.EndsWith(".ymap.xml") && opts.Metadata)
                        {
                            var toDelete = opts.Delete?.Select(e => Convert.ToUInt32(e)).ToList() ?? new List <uint>();

                            var mappings   = new Dictionary <uint, Dictionary <uint, JObject> >();
                            var basePath   = Path.GetDirectoryName(fileInfo.FullName);
                            var ymaps      = new List <YmapFile>();
                            var ymap       = new YmapFile();
                            var nameHashes = new Dictionary <uint, string>();

                            ymap.ResourceFile = res;

                            ymap.Parse();

                            var topParent     = ImportMeta_GetTopYmapParent((uint)ymap.CMapData.Name);
                            var topParentHash = (uint)topParent["hash"];
                            var topParentName = (string)topParent["name"];
                            var topParentPath = (string)topParent["path"];
                            var topParentYmap = new YmapFile();

                            Console.WriteLine("Top parent is " + topParentName);

                            var entries = new List <JObject>()
                            {
                                topParent
                            };

                            entries.AddRange(ImportMeta_GetYmapChildrens(topParent));

                            for (int j = 0; j < entries.Count; j++)
                            {
                                var entry        = entries[j];
                                var entryHash    = (uint)entry["hash"];
                                var entryName    = (string)entry["name"];
                                var entryPath    = (string)entry["path"];
                                var ymapPath     = basePath + "\\" + entryName + ".ymap";
                                var metadataPath = ymapPath + ".json";

                                nameHashes.Add(entryHash, entryName);

                                if (!File.Exists(ymapPath))
                                {
                                    Console.WriteLine("ERROR => File not found : " + entryName + ".ymap");
                                    return;
                                }

                                if (!File.Exists(metadataPath))
                                {
                                    Console.WriteLine("ERROR => Metadata not found for " + entryName);
                                    return;
                                }

                                var metadataMapping = (JArray)JObject.Parse(File.ReadAllText(metadataPath))["mapping"];
                                var mapping         = new Dictionary <uint, JObject>();

                                for (int k = 0; k < metadataMapping.Count; k++)
                                {
                                    mapping.Add((uint)metadataMapping[k]["guid"], (JObject)metadataMapping[k]);
                                }

                                mappings.Add(entryHash, mapping);

                                if (entryHash == (uint)ymap.CMapData.Name)
                                {
                                    ymaps.Add(ymap);
                                }
                                else
                                {
                                    var ymap2 = new YmapFile();
                                    ymap2.Load(ymapPath);
                                    ymaps.Add(ymap2);
                                }
                            }

                            for (int j = 0; j < ymaps.Count; j++)
                            {
                                var ymap2 = ymaps[j];

                                if (ymap2.CMapData.Parent != 0)
                                {
                                    ymap2.CMapData.ParentMapData = ymaps.Find(e => e.CMapData.Name == ymap2.CMapData.Parent).CMapData;
                                }
                            }

                            bool modified;

                            do
                            {
                                modified = false;

                                for (int j = 0; j < ymaps.Count; j++)
                                {
                                    var ymap2 = ymaps[j];

                                    Console.WriteLine(nameHashes[(uint)ymap2.CMapData.Name]);

                                    var toRemove      = new List <MCEntityDef>();
                                    var toSet         = new List <Tuple <MCEntityDef, MCEntityDef> >();
                                    bool currModified = false;

                                    for (int k = 0; k < ymap2.CMapData.Entities.Count; k++)
                                    {
                                        var entity        = ymap2.CMapData.Entities[k];
                                        var oldHasParent  = (bool)mappings[(uint)ymap2.CMapData.Name][entity.Guid]["hasParent"];
                                        var currHasParent = entity.ParentIndex != -1;

                                        if (oldHasParent)
                                        {
                                            var oldParent         = (uint)mappings[(uint)ymap2.CMapData.Name][entity.Guid]["parent"];
                                            var oldParentYmapName = (string)mappings[(uint)ymap2.CMapData.Name][entity.Guid]["parentYmap"];
                                            var oldParentYmap     = Utils.Hash(oldParentYmapName);

                                            if (currHasParent)
                                            {
                                                if (entity.ParentEntity == null || entity.ParentEntity.Guid != oldParent)
                                                {
                                                    var parentYmap = ymaps.Find(e => (uint)e.CMapData.Name == oldParentYmap);
                                                    var parentIdx  = parentYmap.CMapData.Entities.FindIndex(e => e.Guid == oldParent);

                                                    if (parentIdx == -1)
                                                    {
                                                        Console.WriteLine("DELETE " + entity.Guid + " => Missing parent (" + oldParentYmapName + ")");
                                                        toRemove.Add(entity);
                                                        modified     = true;
                                                        currModified = true;
                                                    }
                                                    else
                                                    {
                                                        Console.WriteLine("ASSIGN parent " + oldParent + " to " + entity.Guid);
                                                        var parent = parentYmap.CMapData.Entities[parentIdx];
                                                        toSet.Add(new Tuple <MCEntityDef, MCEntityDef>(entity, parent));
                                                        modified     = true;
                                                        currModified = true;
                                                    }
                                                }
                                                else
                                                {
                                                    if (toDelete.IndexOf(oldParent) != -1 || (opts.DeleteScope == "full" && toDelete.IndexOf(entity.Guid) != -1))
                                                    {
                                                        Console.WriteLine("DELETE " + entity.Guid + " => Marked for deletion @" + opts.DeleteMode);
                                                        toRemove.Add(entity);
                                                        modified     = true;
                                                        currModified = true;
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    if (opts.DeleteMode == "dummy")
                                    {
                                        for (int k = 0; k < toRemove.Count; k++)
                                        {
                                            toRemove[k].ArchetypeName = Utils.Hash("gtautil_dummy");
                                        }
                                    }
                                    else
                                    {
                                        ymap2.CMapData.RemoveEntities(toRemove);
                                    }

                                    for (int k = 0; k < toSet.Count; k++)
                                    {
                                        toSet[k].Item1.ParentEntity = toSet[k].Item2;
                                    }

                                    if (currModified)
                                    {
                                        Console.WriteLine("MODIFIED");
                                    }
                                }
                            } while (modified && opts.DeleteMode != "dummy");

                            for (int j = 0; j < ymaps.Count; j++)
                            {
                                var ymap2   = ymaps[j];
                                var mapping = new Dictionary <uint, int>();
                                var name    = nameHashes[(uint)ymap2.CMapData.Name];

                                ymap2.Save(basePath + "\\" + name + ".ymap");

                                var data = new JObject
                                {
                                    ["mapping"] = new JArray()
                                };

                                var dataMapping = (JArray)(data["mapping"]);

                                for (int k = 0; k < ymap2.CMapData.Entities.Count; k++)
                                {
                                    var entity = ymap2.CMapData.Entities[k];

                                    if (mapping.ContainsKey(entity.Guid))
                                    {
                                        Console.WriteLine("Duplicate GUID found => " + entity.Guid + " at index " + j + " ABORTING");
                                        return;
                                    }
                                    else
                                    {
                                        mapping.Add(entity.Guid, k);

                                        var entry = new JObject()
                                        {
                                            ["guid"]      = entity.Guid,
                                            ["hasParent"] = entity.ParentIndex != -1,
                                        };

                                        if (entity.ParentIndex != -1)
                                        {
                                            entry["parent"]     = entity.ParentEntity.Guid;
                                            entry["parentName"] = MetaXml.HashString((MetaName)entity.ParentEntity.Guid);
                                            entry["parentYmap"] = nameHashes[(uint)entity.ParentEntity.Parent.Name];
                                        }

                                        dataMapping.Add(entry);
                                    }
                                }

                                var jsonString = JsonConvert.SerializeObject(data, new JsonSerializerSettings()
                                {
                                    Formatting = Newtonsoft.Json.Formatting.Indented
                                });

                                File.WriteAllText(basePath + "\\" + name + ".ymap.json", jsonString);
                            }
                        }
                        else
                        {
                            string fileName = fileInfo.FullName.Replace(".xml", "");
                            res.Save(fileName);
                        }
                    }

                    using (StreamWriter writer = new StreamWriter(AssemblyDirectory + "\\strings.txt"))
                    {
                        foreach (var kvp in Jenkins.Index)
                        {
                            writer.Write(kvp.Value + "\n");
                        }
                    }
                }
            });
        }
Пример #2
0
        static void HandleExportMetaOptions(string[] args)
        {
            CommandLine.Parse <ExportMetaOptions>(args, (opts, gOpts) =>
            {
                if (opts.Metadata)
                {
                    Init(args);
                }
                else
                {
                    EnsurePath();
                    EnsureKeys();
                    EnsureCache();
                }

                if (opts.InputFiles == null)
                {
                    Console.WriteLine("Please provide input files with -i --input");
                    return;
                }
                else
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        Console.WriteLine(fileInfo.FullName);

                        MetaFile meta = null;

                        if (fileInfo.Name.EndsWith(".ymap") && opts.Metadata)
                        {
                            var ymap = new YmapFile();

                            ymap.Load(fileInfo.FullName);

                            meta = ymap.ResourceFile.ResourceData;

                            var basePath      = Path.GetDirectoryName(fileInfo.FullName);
                            var topParent     = ImportMeta_GetTopYmapParent((uint)ymap.CMapData.Name);
                            var topParentHash = (uint)topParent["hash"];
                            var topParentName = (string)topParent["name"];
                            var topParentPath = (string)topParent["path"];
                            var topParentYmap = new YmapFile();

                            Console.WriteLine("Top parent is " + topParentName);

                            if (File.Exists(basePath + "\\" + topParentName + ".ymap"))
                            {
                                topParentYmap.Load(basePath + "\\" + topParentName + ".ymap");
                            }
                            else
                            {
                                ArchiveUtilities.ForEachResourceFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                                {
                                    if (fullFileName == topParentPath)
                                    {
                                        var ms = new MemoryStream();
                                        file.Export(ms);
                                        topParentYmap.Load(ms);
                                    }
                                });
                            }

                            var children = ImportMeta_GetYmapChildrens(topParent);
                            var ymaps    = new List <YmapFile>()
                            {
                                topParentYmap
                            };
                            var nameHashes = new Dictionary <uint, string>();

                            nameHashes.Add((uint)topParent["hash"], (string)topParent["name"]);

                            for (int j = 0; j < children.Count; j++)
                            {
                                var cYmap = new YmapFile();
                                var child = children[j];
                                var hash  = (uint)child["hash"];
                                var name  = (string)child["name"];
                                var path  = (string)child["path"];

                                nameHashes.Add(hash, name);

                                if (File.Exists(basePath + "\\" + name + ".ymap"))
                                {
                                    cYmap.Load(basePath + "\\" + name + ".ymap");
                                }
                                else
                                {
                                    Console.WriteLine("Grabbing missing " + name + " from install directory (very slowly, needs optimization)");

                                    ArchiveUtilities.ForEachResourceFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                                    {
                                        if (fullFileName == path)
                                        {
                                            var ms = new MemoryStream();

                                            file.Export(ms);

                                            cYmap.Load(ms);
                                        }
                                    });
                                }

                                ymaps.Add(cYmap);
                            }

                            ymaps[ymaps.FindIndex(e => e.CMapData.Name == ymap.CMapData.Name)] = ymap;

                            for (int j = 0; j < ymaps.Count; j++)
                            {
                                ymaps[j].CMapData.ParentMapData = ymaps.Find(e => e.CMapData.Name == ymaps[j].CMapData.Parent)?.CMapData;
                            }

                            for (int j = 0; j < ymaps.Count; j++)
                            {
                                var ymap2   = ymaps[j];
                                var mapping = new Dictionary <uint, int>();
                                var name    = nameHashes[(uint)ymap2.CMapData.Name];

                                ymap2.Save(basePath + "\\" + name + ".ymap");

                                var data = new JObject
                                {
                                    ["mapping"] = new JArray()
                                };

                                var dataMapping = (JArray)(data["mapping"]);

                                for (int k = 0; k < ymap2.CMapData.Entities.Count; k++)
                                {
                                    var entity = ymap2.CMapData.Entities[k];

                                    if (mapping.ContainsKey(entity.Guid))
                                    {
                                        Console.WriteLine("Duplicate GUID found => " + entity.Guid + " at index " + j + " ABORTING");
                                        return;
                                    }
                                    else
                                    {
                                        mapping.Add(entity.Guid, k);

                                        var entry = new JObject()
                                        {
                                            ["guid"]      = entity.Guid,
                                            ["hasParent"] = entity.ParentIndex != -1,
                                        };

                                        if (entity.ParentIndex != -1)
                                        {
                                            entry["parent"]     = entity.ParentEntity.Guid;
                                            entry["parentName"] = MetaXml.HashString((MetaName)entity.ParentEntity.Guid);
                                            entry["parentYmap"] = nameHashes[(uint)entity.ParentEntity.Parent.Name];
                                        }

                                        dataMapping.Add(entry);
                                    }
                                }

                                var jsonString = JsonConvert.SerializeObject(data, new JsonSerializerSettings()
                                {
                                    Formatting = Newtonsoft.Json.Formatting.Indented
                                });

                                File.WriteAllText(basePath + "\\" + name + ".ymap.json", jsonString);
                            }
                        }
                        else
                        {
                            var res = new ResourceFile_GTA5_pc <MetaFile>();
                            res.Load(fileInfo.FullName);
                            meta = res.ResourceData;
                        }

                        var xml = MetaXml.GetXml(meta);

                        string fileName = fileInfo.FullName + ".xml";

                        File.WriteAllText(fileName, xml);
                    }
                }
            });
        }