public static void EnsureArchetypes(int targetDlcLevel) { Console.Error.WriteLine("Loading archetypes"); ArchiveUtilities.ForEachResourceFile(Settings.Default.GTAFolder, (string fullFileName, IArchiveResourceFile file, RageArchiveEncryption7 encryption) => { var dlcLevel = GetDLCLevel(fullFileName); if (dlcLevel > targetDlcLevel) { return; } if (file.Name.EndsWith(".ytyp")) { var ytyp = new YtypFile(); using (var ms = new MemoryStream()) { file.Export(ms); ytyp.Load(ms); } for (int i = 0; i < ytyp.CMapTypes.Archetypes.Count; i++) { var archetype = ytyp.CMapTypes.Archetypes[i]; ArchetypeCache[(uint)archetype.Name] = archetype; } } }); }
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); } } }); }
static void HandleCompileDrawableShadersOptions(string[] args) { CommandLine.Parse <CompileDrawableShadersOptions>(args, (opts, gOpts) => { EnsurePath(); EnsureKeys(); var shaderNames = new Dictionary <uint, string>(); var shaderParameterSetNames = new Dictionary <uint, string>(); var fxcShaders = new Dictionary <uint, FxcFile>(); ArchiveUtilities.ForEachBinaryFile(Settings.Default.GTAFolder, (fullFileName, binaryFile, encryption) => { if (fullFileName.EndsWith(".fxc")) { string nameLower = binaryFile.Name.ToLowerInvariant().Replace(".fxc", ""); var hash = Jenkins.Hash(nameLower); if (!shaderNames.ContainsKey(hash)) { shaderNames.Add(hash, nameLower); } byte[] data = Utils.GetBinaryFileData((IArchiveBinaryFile)binaryFile, encryption); var fxc = new FxcFile(); fxc.Load(data, nameLower); if (!fxcShaders.ContainsKey(hash)) { fxcShaders.Add(hash, fxc); } } else if (fullFileName.EndsWith(".sps")) { string nameLower = binaryFile.Name.ToLowerInvariant(); var hash = Jenkins.Hash(nameLower); if (!shaderParameterSetNames.ContainsKey(hash)) { shaderParameterSetNames.Add(hash, nameLower); } } }); ArchiveUtilities.ForEachResourceFile(Settings.Default.GTAFolder, (fullFileName, resourceFile, encryption) => { if (fullFileName.EndsWith(".ydr")) { var ms = new MemoryStream(); resourceFile.Export(ms); var ydr = new YdrFile(); ydr.Load(ms); Console.WriteLine(fullFileName.Replace(Settings.Default.GTAFolder, "")); CompileDrawableShaders_ProcessDrawable(ydr.Drawable, shaderNames, fxcShaders); Console.WriteLine(""); } else if (fullFileName.EndsWith(".ydd")) { var ms = new MemoryStream(); resourceFile.Export(ms); var ydd = new YddFile(); ydd.Load(ms); Console.WriteLine(fullFileName.Replace(Settings.Default.GTAFolder, "")); var drawables = ydd.DrawableDictionary.Drawables; for (int d = 0; d < drawables.Count; d++) { var drawable = drawables[d]; Console.WriteLine(" " + drawable.Name.Value); CompileDrawableShaders_ProcessDrawable(drawable, shaderNames, fxcShaders); } Console.WriteLine(""); } }); }); }
static void HandleGenLODLightsOptions(string[] args) { CommandLine.Parse <GenLODLigthsOptions>(args, (opts, gOpts) => { if (opts.CreateMode) { if (opts.OutputDirectory == null) { Console.Error.WriteLine("Please provide output directory with --output"); return; } Init(args); if (!Directory.Exists(opts.OutputDirectory)) { Directory.CreateDirectory(opts.OutputDirectory); } var mapping = new Dictionary <string, int>(); ArchiveUtilities.ForEachResourceFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) => { if (file.Name.EndsWith(".ymap") && file.Name.Contains("lodlights")) { Console.WriteLine(file.Name); int level = GetDLCLevel(fullFileName); int oldLevel; if (!mapping.TryGetValue(file.Name, out oldLevel)) { oldLevel = -1; mapping.Add(file.Name, level); } if (level > oldLevel) { file.Export(opts.OutputDirectory + "\\" + file.Name); } } }); } else if (opts.DeleteMode) { Init(args); if (opts.InputDirectory == null) { Console.Error.WriteLine("Please provide input directory with --input"); return; } if (opts.Position == null || opts.Position.Count != 3) { Console.Error.WriteLine("Please provide position with --position x,y,z"); return; } if (!Directory.Exists(opts.InputDirectory + "\\modified")) { Directory.CreateDirectory(opts.InputDirectory + "\\modified"); } Vector3 position = new Vector3(opts.Position[0], opts.Position[1], opts.Position[2]); string[] files = Directory.GetFiles(opts.InputDirectory, "*.ymap"); var ymaps = new Dictionary <string, YmapFile>(); for (int i = 0; i < files.Length; i++) { string path = files[i]; string name = files[i].Replace(".ymap", ""); var ymap = new YmapFile(); Console.WriteLine("LOAD " + name); ymap.Load(files[i]); ymaps.Add(name, ymap); } var modified = new Dictionary <string, YmapFile>(); foreach (var item in ymaps) { string name = item.Key; YmapFile ymap = item.Value; for (int j = ymap.CMapData.DistantLODLightsSOA.Entries.Count - 1; j >= 0; j--) { var entry = ymap.CMapData.DistantLODLightsSOA.Entries[j]; var children = new Dictionary <string, YmapFile>(); float distance = Vector3.Distance(position, entry.Position); foreach (var item2 in ymaps) { if (item2.Value.CMapData.Parent == ymap.CMapData.Name) { children.Add(item2.Key, item2.Value); } } if (distance <= opts.Radius) { Console.WriteLine("Found DistLODLight in " + name + " at index " + j); Console.WriteLine(" Delete : " + name + "@" + j); ymap.CMapData.DistantLODLightsSOA.Entries.RemoveAt(j); if (!modified.ContainsValue(ymap)) { modified.Add(name, ymap); } foreach (var item2 in children) { string name2 = item2.Key; YmapFile ymap2 = item2.Value; Console.WriteLine(" Delete : " + name2 + "@" + j); item2.Value.CMapData.LODLightsSOA.Entries.RemoveAt(j); if (!modified.ContainsValue(ymap2)) { modified.Add(name2, ymap2); } } } } } foreach (var item in modified) { var descendant = item.Key.Substring(item.Key.LastIndexOf("\\")); item.Value.Save(opts.InputDirectory + "\\" + descendant + ".ymap"); item.Value.Save(opts.InputDirectory + "\\modified\\" + descendant + ".ymap"); } } }); }
// WIP++ static void HandlYmapToYdrOptions(string[] args) { CommandLine.Parse <YmapToYdrOptions>(args, (opts, gOpts) => { Init(args); var files = new Dictionary <uint, string>(); var required = new List <uint>(); var ymap = new YmapFile(); ymap.Load(opts.InputFile); for (int i = 0; i < ymap.CMapData.Entities.Count; i++) { var entity = ymap.CMapData.Entities[i]; if (required.IndexOf(entity.ArchetypeName) == -1) { required.Add(entity.ArchetypeName); } } ArchiveUtilities.ForEachResourceFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) => { if (file.Name.EndsWith(".ydr")) { uint hash = Utils.Hash(file.Name.ToLowerInvariant().Replace(".ydr", "")); if (required.IndexOf(hash) != -1 && !files.ContainsKey(hash)) { Console.WriteLine(file.Name); string tmp = Path.GetTempFileName(); file.Export(tmp); files.Add(hash, tmp); } } }); YdrFile ydr = null; var bbMin = new Vector3(float.MaxValue); var bbMax = new Vector3(float.MinValue); var bsCenter = Vector3.Zero; foreach (var file in files) { var ydr2 = new YdrFile(); ydr2.Load(file.Value); bbMin = Vector3.Min(bbMin, (Vector3)(Vector4)ydr2.Drawable.BoundingBoxMin); bbMax = Vector3.Max(bbMin, (Vector3)(Vector4)ydr2.Drawable.BoundingBoxMax); if (ydr == null) { ydr = ydr2; continue; } ydr.Drawable.BoundingSphereRadius = ydr2.Drawable.BoundingSphereRadius; for (int i = 0; i < ydr2.Drawable.DrawableModelsHigh.Entries.Count; i++) { var model = ydr2.Drawable.DrawableModelsHigh.Entries[i]; for (int j = 0; j < model.Geometries.Count; j++) { ydr.Drawable.DrawableModelsHigh.Entries[i].Geometries.Add(model.Geometries[j]); } } for (int i = 0; i < ydr2.Drawable.DrawableModelsX.Entries.Count; i++) { var model = ydr2.Drawable.DrawableModelsX.Entries[i]; for (int j = 0; j < model.Geometries.Count; j++) { ydr.Drawable.DrawableModelsX.Entries[i].Geometries.Add(model.Geometries[j]); } } } ydr.Drawable.BoundingBoxMin = (RAGE_Vector4)(Vector4)bbMin; ydr.Drawable.BoundingBoxMax = (RAGE_Vector4)(Vector4)bbMax; ydr.Drawable.BoundingCenter = (RAGE_Vector3)bsCenter; ydr.Save(opts.OutputFile); }); }