예제 #1
0
        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;
                    }
                }
            });
        }
예제 #2
0
        public static void EnsureFiles(int targetDlcLevel)
        {
            Console.Error.WriteLine("Loading file tree");

            ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (string fullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
            {
                var dlcLevel = GetDLCLevel(fullFileName);

                if (dlcLevel > targetDlcLevel)
                {
                    return;
                }

                string[] path  = fullFileName.Split('\\');
                string[] split = path[path.Length - 1].ToLowerInvariant().Split('.');
                string name    = split[0];
                string ext     = split[split.Length - 1];
                uint hash      = Jenkins.Hash(name);

                var rpfEntry = new RpfFileEntry()
                {
                    Hash         = hash,
                    Name         = fullFileName.Replace('/', '\\').ToLowerInvariant().Split('\\').Last(),
                    FullFileName = fullFileName,
                    DlcLevel     = dlcLevel,
                    Ext          = ext,
                };

                if (DLCFiles.ContainsKey(rpfEntry.Name))
                {
                    if (rpfEntry.DlcLevel > DLCFiles[rpfEntry.Name].DlcLevel)
                    {
                        DLCFiles[rpfEntry.Name] = rpfEntry;
                    }
                }
                else
                {
                    DLCFiles[rpfEntry.Name] = rpfEntry;
                }

                Files.Add(rpfEntry);

                Dictionary <uint, RpfFileEntry> dict;

                if (!(FileHashes.TryGetValue(ext, out dict)))
                {
                    dict = new Dictionary <uint, RpfFileEntry>();
                }

                dict[hash] = rpfEntry;

                FileHashes[ext] = dict;
            });
        }
예제 #3
0
        public void OnApplicationRequestOpenProject()
        {
            var ofd = new CommonOpenFileDialog();

            ofd.Title                     = "Choose Directory";
            ofd.IsFolderPicker            = true;
            ofd.AddToMostRecentlyUsedList = false;
            ofd.AllowNonFileSystemItems   = false;
            ofd.EnsureFileExists          = true;
            ofd.EnsurePathExists          = true;
            ofd.EnsureReadOnly            = false;
            ofd.EnsureValidNames          = true;
            ofd.Multiselect               = false;
            ofd.ShowPlacesList            = true;

            if (ofd.ShowDialog() == CommonFileDialogResult.Ok)
            {
                List <string> files = new List <string>(Directory.GetFiles(ofd.FileName));

                // There were no files in the directory, so we'll assume the map is already extracted
                if (files.Count == 0)
                {
                    // Just assume the folder paths are valid now.
                    LoadProject(ofd.FileName, ofd.FileName);
                }
                // We'll have to dump the contents of the arcs
                else
                {
                    string tempMapPath = Path.GetTempPath() + Path.GetFileName(ofd.FileName); // This is where we'll dump the arc contents to

                    if (!Directory.Exists(tempMapPath))
                    {
                        Directory.CreateDirectory(tempMapPath);
                    }

                    foreach (var arc in files)
                    {
                        VirtualFilesystemDirectory archiveRoot = ArchiveUtilities.LoadArchive(arc);
                        string tempArcPath = $"{tempMapPath}\\{archiveRoot.Name}";

                        if (!Directory.Exists(tempArcPath))
                        {
                            Directory.CreateDirectory(tempMapPath);
                        }

                        DumpContents(archiveRoot, tempArcPath);
                    }

                    LoadProject(tempMapPath, ofd.FileName);
                }
            }
        }
예제 #4
0
        private void UpdateModel()
        {
            // Loads the necessary information about which figurine model to load dynamically from the REL and the DOL.

            m_actorMeshes = WResourceManager.LoadActorResource("Figurine Stand");

            int modelFileID;
            int modelArcIndex;

            int figurineIndex = (int)WhichFigurine;

            string       figurine_rel_path = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "files", "rels/d_a_obj_figure.rel");
            MemoryStream figurine_rel_data = null;

            using (EndianBinaryReader reader = new EndianBinaryReader(File.ReadAllBytes(figurine_rel_path), Endian.Big))
            {
                figurine_rel_data = Yaz0.Decode(reader);
            }
            using (EndianBinaryReader reader = new EndianBinaryReader(figurine_rel_data, Endian.Big))
            {
                int l_figure_dat_entry_offset = l_figure_dat_tbl_offset + figurineIndex * 0xC;
                modelFileID   = reader.ReadInt32At(l_figure_dat_entry_offset + 0x00);
                modelArcIndex = reader.ReadInt32At(l_figure_dat_entry_offset + 0x08);
            }

            if (modelArcIndex == -1)
            {
                string main_dol_path = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "sys", "main.dol");
                using (FileStream strm = new FileStream(main_dol_path, FileMode.Open, FileAccess.Read))
                {
                    EndianBinaryReader reader      = new EndianBinaryReader(strm, Endian.Big);
                    long l_CharaData_entry_address = l_CharaData_address + figurineIndex * 0x12;
                    long l_CharaData_entry_offset  = DOL.AddressToOffset(l_CharaData_entry_address, reader);
                    modelArcIndex = reader.ReadByteAt(l_CharaData_entry_offset + 0x10);
                }
            }

            var    arc_name = l_arcname_tbl[modelArcIndex];
            string arc_path = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "files", "res/Object/", arc_name + ".arc");

            if (File.Exists(arc_path))
            {
                VirtualFilesystemDirectory model_arc = ArchiveUtilities.LoadArchive(arc_path);
                if (model_arc.FindByID((ushort)modelFileID) != null)
                {
                    var figurine_model = WResourceManager.LoadModelFromVFS(model_arc, fileID: (ushort)modelFileID);
                    figurine_model.SetOffsetTranslation(new Vector3(0, 100, 0));
                    m_actorMeshes.Add(figurine_model);
                }
            }
        }
예제 #5
0
        private bool DownloadWebDriver(IWebBrowserInfo webBrowserInfo, CancellationToken cancellationToken)
        {
            string webDriverExecutablePath = GetWebDriverExecutablePathInternal();

            OnLog.Info("Getting web driver download url");

            Uri    webDriverDownloadUri = GetWebDriverUri(webBrowserInfo, webRequestFactory);
            string downloadFilePath     = PathUtilities.SetFileExtension(Path.GetTempFileName(), ".zip");

            if (webDriverDownloadUri is object)
            {
                OnLog.Info($"Downloading {webDriverDownloadUri}");

                using (IWebClient webClient = webRequestFactory.ToWebClientFactory().Create()) {
                    webClient.DownloadProgressChanged += (sender, e) => OnDownloadFileProgressChanged(this, new DownloadFileProgressChangedEventArgs(webDriverDownloadUri, downloadFilePath, e));
                    webClient.DownloadFileCompleted   += (sender, e) => OnDownloadFileCompleted(this, new DownloadFileCompletedEventArgs(webDriverDownloadUri, downloadFilePath, e.Error is null));

                    webClient.DownloadFileSync(webDriverDownloadUri, downloadFilePath, cancellationToken);
                }

                try {
                    string filePathInArchive = PathUtilities.GetFilename(webDriverExecutablePath);

                    OnLog.Info($"Extracting {filePathInArchive}");

                    ArchiveUtilities.ExtractFile(downloadFilePath, filePathInArchive, webDriverExecutablePath);
                }
                catch (Exception ex) {
                    OnLog.Error(ex.ToString());

                    throw ex;
                }
                finally {
                    File.Delete(downloadFilePath);
                }

                // We were able to successfully update the web driver.

                return(true);
            }

            // We were not able to successfully update the web driver.

            return(false);
        }
예제 #6
0
        public IEnumerable <Category> Load(string fileName)
        {
            using (FileStream stream = new FileStream(fileName, FileMode.Open))
            {
                VirtualFilesystemDirectory rootDir = ArchiveUtilities.LoadArchive(fileName);

                foreach (VirtualFilesystemNode node in rootDir.Children)
                {
                    if (node.Name.Contains("dzb"))
                    {
                        return(GetDzbData((VirtualFilesystemDirectory)node));
                    }
                }
            }

            // If this is triggered, the archive the user opened wasn't a room archive and didn't have any DZBs in it
            return(null);
        }
예제 #7
0
        static void HandleCompileGxt2Options(string[] args)
        {
            CommandLine.Parse <CompileGxt2Optionns>(args, (opts, gOpts) =>
            {
                Init(args);

                if (opts.OutputDirectory == null)
                {
                    Console.WriteLine("Please provide output directory with -o --output");
                    return;
                }

                var entries = new Dictionary <uint, string>();

                ArchiveUtilities.ForEachBinaryFile(Settings.Default.GTAFolder, (string fullFileName, IArchiveBinaryFile file, RageArchiveEncryption7 encryption) =>
                {
                    if (fullFileName.EndsWith(".gxt2") && fullFileName.ToLowerInvariant().Contains(opts.Lang.ToLowerInvariant()))
                    {
                        Console.WriteLine(fullFileName);

                        var gxt2    = new Gxt2File();
                        byte[] data = Utils.GetBinaryFileData(file, encryption);

                        gxt2.Load(data);

                        for (int i = 0; i < gxt2.TextEntries.Count; i++)
                        {
                            entries[gxt2.TextEntries[i].Hash] = gxt2.TextEntries[i].Text;
                        }
                    }
                });

                var sb = new StringBuilder();

                foreach (var entry in entries)
                {
                    sb.AppendLine(entry.Key + " = " + entry.Value);
                }

                File.WriteAllText(opts.OutputDirectory + "\\" + opts.Lang + ".gxt2.txt", sb.ToString());
            });
        }
예제 #8
0
        private bool TryLoadMessageArchive()
        {
            string bmgres_path = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "files", "res", "Msg", "bmgres.arc");

            if (!File.Exists(bmgres_path))
            {
                return(false);
            }

            m_MessageArchive = ArchiveUtilities.LoadArchive(bmgres_path);

            VirtualFilesystemFile text_bank = m_MessageArchive.GetFileAtPath("zel_00.bmg");

            using (MemoryStream strm = new MemoryStream(text_bank.Data))
            {
                EndianBinaryReader reader = new EndianBinaryReader(strm, Endian.Big);
                LoadMessageData(reader);
            }

            return(true);
        }
예제 #9
0
        public static void ForFile(string fullFileName, Action <IArchiveFile, RageArchiveEncryption7> cb)
        {
            fullFileName = fullFileName.Replace('/', '\\').Replace(Settings.Default.GTAFolder + "\\", "");
            string[] split = fullFileName.Split(new string[] { ".rpf" }, StringSplitOptions.None);

            for (int i = 0; i < split.Length - 1; i++)
            {
                split[i] = split[i] + ".rpf";
            }

            var baseRpf = Settings.Default.GTAFolder + "\\" + split[0];

            try
            {
                var fileInfo   = new FileInfo(baseRpf);
                var fileStream = new FileStream(baseRpf, FileMode.Open);

                var inputArchive = RageArchiveWrapper7.Open(fileStream, fileInfo.Name);

                ArchiveUtilities.ForEachFile(split[0], inputArchive.Root, inputArchive.archive_.Encryption, (string currFullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
                {
                    currFullFileName = currFullFileName.Replace('/', '\\');

                    if (currFullFileName == fullFileName)
                    {
                        cb(file, encryption);
                    }
                });

                inputArchive.Dispose();
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);
            }
        }
예제 #10
0
파일: Program.cs 프로젝트: tracid56/gtautil
        static void Main(string[] args)
        {
            EnsurePath();
            EnsureKeys();
            EnsureCache();

            CommandLine.Parse <GenPropDefsOptions>(args, opts =>
            {
                if (opts.InputFiles != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);
                    var ytyp       = new YtypFile();

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

                        string name = "";
                        var split   = fileInfo.Name.Split('.');

                        for (int j = 0; j < split.Length; j++)
                        {
                            if (j < split.Length - 1)
                            {
                                if (j > 0)
                                {
                                    name += ".";
                                }

                                name += split[j];
                            }
                        }

                        Console.WriteLine(name);

                        try
                        {
                            switch (fileInfo.Extension)
                            {
                            case ".ydr":
                                {
                                    var ydr      = new YdrFile();
                                    var arch     = new RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CBaseArchetypeDef();
                                    var nameHash = (MetaName)Jenkins.Hash(name);

                                    ydr.Load(fileInfo.FullName);

                                    arch.Name              = nameHash;
                                    arch.AssetName         = nameHash;
                                    arch.TextureDictionary = nameHash;
                                    arch.PhysicsDictionary = (MetaName)Jenkins.Hash("prop_" + name);
                                    arch.Flags             = 32;
                                    arch.AssetType         = Unk_1991964615.ASSET_TYPE_DRAWABLE;
                                    arch.BbMin             = (Vector3)(Vector4)ydr.Drawable.BoundingBoxMin;
                                    arch.BbMax             = (Vector3)(Vector4)ydr.Drawable.BoundingBoxMax;
                                    arch.BsCentre          = (Vector3)ydr.Drawable.BoundingCenter;
                                    arch.BsRadius          = ydr.Drawable.BoundingSphereRadius;
                                    arch.LodDist           = 500f;
                                    arch.HdTextureDist     = 5;

                                    ytyp.CMapTypes.Archetypes.Add(arch);

                                    break;
                                }

                            case ".ydd":     // TODO
                                {
                                    break;
                                }

                            default: break;
                            }
                        }
                        catch (Exception e)
                        {
                            Console.Error.WriteLine("ERROR => " + e.Message);
                        }
                    }

                    string path = (opts.Directory == null) ? @".\props.ytyp" : opts.Directory + @"\props.ytyp";

                    ytyp.Save(path);
                }
            });

            CommandLine.Parse <ImportMetaOptions>(args, opts =>
            {
                if (opts.InputFiles != null && opts.Directory != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

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

                        Console.WriteLine(fileInfo.FullName);

                        var doc = new XmlDocument();

                        doc.Load(fileInfo.FullName);

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

                        string fileName = fileInfo.FullName.Replace(".xml", "");

                        res.Save(fileName);
                    }
                }
            });

            CommandLine.Parse <ExportMetaOptions>(args, opts =>
            {
                if (opts.InputFiles != null && opts.Directory != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

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

                        Console.WriteLine(fileInfo.FullName);

                        var res = new ResourceFile_GTA5_pc <MetaFile>();
                        res.Load(fileInfo.FullName);

                        var xml = MetaXml.GetXml(res.ResourceData);

                        File.WriteAllText(opts.Directory + "\\" + fileInfo.Name + ".xml", xml);
                    }
                }
            });

            CommandLine.Parse <InjectEntitiesOptions>(args, opts =>
            {
                if (opts.Ymap == null)
                {
                    Console.WriteLine("Please provide source ymap file with --ymap");
                    return;
                }

                if (opts.Ytyp == null)
                {
                    Console.WriteLine("Please provide source ytyp file with --ytyp");
                    return;
                }

                if (opts.Room == null)
                {
                    Console.WriteLine("Please provide mlo room name with --room");
                    return;
                }

                if (opts.Position == null || opts.Position.Count() != 3)
                {
                    Console.WriteLine("Please provide a correct position ex: --position 120.5,1370.312,769.2");
                    return;
                }

                if (opts.Rotation == null || opts.Rotation.Count() != 4)
                {
                    Console.WriteLine("Plase provide a correct rotation ex: --rotation 0,0,0,1");
                    return;
                }

                if (opts.Name == null)
                {
                    Console.WriteLine("Plase provide new generated ytyp name with --name");
                    return;
                }

                var position = new Vector3(opts.Position.ElementAt(0), opts.Position.ElementAt(1), opts.Position.ElementAt(2));
                var rotation = new Quaternion(opts.Rotation.ElementAt(0), opts.Rotation.ElementAt(1), opts.Rotation.ElementAt(2), opts.Rotation.ElementAt(3));

                var ymap = new YmapFile();
                var ytyp = new YtypFile();

                ymap.Load(opts.Ymap);
                ytyp.Load(opts.Ytyp);

                RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CMloArchetypeDef mlo = null;

                for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                {
                    mlo = ytyp.CMapTypes.MloArchetypes[i];
                    break;
                }

                if (mlo == null)
                {
                    Console.WriteLine("MLO archetype not found");
                    return;
                }

                RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CMloRoomDef room = null;

                for (int i = 0; i < mlo.Rooms.Count; i++)
                {
                    if (mlo.Rooms[i].Name == opts.Room)
                    {
                        room = mlo.Rooms[i];
                        break;
                    }
                }

                if (room == null)
                {
                    Console.WriteLine("MLO room not found");
                    return;
                }

                var mloEntities     = new List <RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CEntityDef>();
                var attachedObjects = new List <uint>();

                mloEntities.AddRange(mlo.Entities);
                attachedObjects.AddRange(room.AttachedObjects);

                for (int i = 0; i < ymap.CMapData.Entities.Count; i++)
                {
                    var entity       = ymap.CMapData.Entities[i];
                    var mloRot       = rotation;
                    var objRot       = new Quaternion(entity.Rotation.X, entity.Rotation.Y, entity.Rotation.Z, entity.Rotation.W);
                    var rotationDiff = objRot * mloRot;                                                                    // Multiply initial entity rotation by mlo rotation

                    entity.Position -= position;                                                                           // Substract mlo world coords from entity world coords
                    entity.Position  = Utils.RotateTransform(Quaternion.Conjugate(mloRot), entity.Position, Vector3.Zero); // Rotate entity around center of mlo instance (mlo entities rotations in space are inverted)
                    entity.Rotation  = new Vector4(rotationDiff.X, rotationDiff.Y, rotationDiff.Z, rotationDiff.W);

                    mloEntities.Add(entity);
                    attachedObjects.Add((uint)mloEntities.IndexOf(entity));
                }

                mlo.Entities         = mloEntities;
                room.AttachedObjects = attachedObjects;

                ytyp.Save(opts.Name.EndsWith(".ytyp") ? opts.Name : opts.Name + ".ytyp");
            });

            CommandLine.Parse <FindOptions>(args, opts =>
            {
                if (opts.Position == null || opts.Position.Count != 3)
                {
                    Console.Error.WriteLine("Please specify position with -p --position");
                    return;
                }

                if (Cache == null)
                {
                    Console.Error.WriteLine("Please build cache first with buildcache");
                    return;
                }

                var c = CultureInfo.InvariantCulture;

                for (int i = 0; i < Cache["ymap"].Count; i++)
                {
                    var cYmap = Cache["ymap"][i];

                    var entitiesExtentsMin = new Vector3((float)cYmap["entitiesExtentsMin"]["x"], (float)cYmap["entitiesExtentsMin"]["y"], (float)cYmap["entitiesExtentsMin"]["z"]);
                    var entitiesExtentsMax = new Vector3((float)cYmap["entitiesExtentsMax"]["x"], (float)cYmap["entitiesExtentsMax"]["y"], (float)cYmap["entitiesExtentsMax"]["z"]);

                    if (
                        opts.Position[0] >= entitiesExtentsMin.X && opts.Position[0] <= entitiesExtentsMax.X &&
                        opts.Position[1] >= entitiesExtentsMin.Y && opts.Position[1] <= entitiesExtentsMax.Y &&
                        opts.Position[2] >= entitiesExtentsMin.Z && opts.Position[2] <= entitiesExtentsMax.Z
                        )
                    {
                        Console.WriteLine("ymap: " + ((string)cYmap["path"]).Split('\\').Last());

                        for (int j = 0; j < cYmap["mloInstances"].Count; j++)
                        {
                            var cMloInstance     = cYmap["mloInstances"][j];
                            var cMloInstanceHash = (uint)cMloInstance["name"];

                            var instancePos = new Vector3((float)cMloInstance["position"]["x"], (float)cMloInstance["position"]["y"], (float)cMloInstance["position"]["z"]);
                            var instanceRot = new Quaternion((float)cMloInstance["rotation"]["x"], (float)cMloInstance["rotation"]["y"], (float)cMloInstance["rotation"]["z"], (float)cMloInstance["rotation"]["w"]);

                            for (int k = 0; k < Cache["ytyp"].Count; k++)
                            {
                                var cYtyp     = Cache["ytyp"][k];
                                var cYtypHash = (uint)cYtyp["hash"];

                                for (int l = 0; l < cYtyp["mloArchetypes"].Count; l++)
                                {
                                    var cMloArch     = cYtyp["mloArchetypes"][l];
                                    var cMloArchHash = (uint)cMloArch["name"];

                                    if (cMloInstanceHash == cMloArchHash)
                                    {
                                        Console.WriteLine("  ytyp => " + ((string)cYtyp["path"]).Split('\\').Last());
                                        Console.WriteLine("    mlo => " + Jenkins.GetString(cMloArchHash));
                                        Console.WriteLine("    position => " + instancePos.X.ToString(c) + "," + instancePos.Y.ToString(c) + "," + instancePos.Z.ToString(c));
                                        Console.WriteLine("    rotation => " + instanceRot.X.ToString(c) + "," + instanceRot.Y.ToString(c) + "," + instanceRot.Z.ToString(c) + "," + instanceRot.W.ToString(c));

                                        for (int m = 0; m < cMloArch["rooms"].Count; m++)
                                        {
                                            var cMloRoom = cMloArch["rooms"][m];

                                            var roomBbMin = new Vector3((float)cMloRoom["bbMin"]["x"], (float)cMloRoom["bbMin"]["y"], (float)cMloRoom["bbMin"]["z"]);
                                            var roomBbMax = new Vector3((float)cMloRoom["bbMax"]["x"], (float)cMloRoom["bbMax"]["y"], (float)cMloRoom["bbMax"]["z"]);

                                            var roomBbMinWorld = instancePos + roomBbMin;
                                            var roomBbMaxWorld = instancePos + roomBbMax;

                                            roomBbMinWorld = Utils.RotateTransform(Quaternion.Conjugate(instanceRot), roomBbMinWorld, Vector3.Zero);
                                            roomBbMaxWorld = Utils.RotateTransform(Quaternion.Conjugate(instanceRot), roomBbMaxWorld, Vector3.Zero);

                                            if (
                                                opts.Position[0] >= roomBbMinWorld.X && opts.Position[0] <= roomBbMaxWorld.X &&
                                                opts.Position[1] >= roomBbMinWorld.Y && opts.Position[1] <= roomBbMaxWorld.Y &&
                                                opts.Position[2] >= roomBbMinWorld.Z && opts.Position[2] <= roomBbMaxWorld.Z
                                                )
                                            {
                                                Console.WriteLine("      room => " + cMloRoom["name"]);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        Console.WriteLine("");
                    }
                }
            });

            CommandLine.Parse <BuildCacheOptions>(args, opts =>
            {
                dynamic cache = new JObject();

                cache["ymap"] = new JArray();
                cache["ytyp"] = new JArray();

                ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                {
                    Console.WriteLine(fullFileName);

                    string fileNameWithoutExtension = file.Name.Split('.').First();

                    Jenkins.Ensure(fileNameWithoutExtension);

                    if (file.Name.EndsWith(".ymap"))
                    {
                        var ymap = new YmapFile();

                        using (MemoryStream ms = new MemoryStream())
                        {
                            file.Export(ms);
                            ymap.Load(ms);
                        }

                        dynamic entry = new JObject()
                        {
                            ["name"] = fileNameWithoutExtension,
                            ["path"] = fullFileName,
                            ["hash"] = Jenkins.Hash(fileNameWithoutExtension),
                            ["entitiesExtentsMin"] = new JObject()
                            {
                                ["x"] = ymap.CMapData.EntitiesExtentsMin.X,
                                ["y"] = ymap.CMapData.EntitiesExtentsMin.Y,
                                ["z"] = ymap.CMapData.EntitiesExtentsMin.Z,
                            },
                            ["entitiesExtentsMax"] = new JObject()
                            {
                                ["x"] = ymap.CMapData.EntitiesExtentsMax.X,
                                ["y"] = ymap.CMapData.EntitiesExtentsMax.Y,
                                ["z"] = ymap.CMapData.EntitiesExtentsMax.Z,
                            },
                            ["mloInstances"] = new JArray(),
                        };

                        if (ymap.CMapData.MloInstances != null)
                        {
                            for (int i = 0; i < ymap.CMapData.MloInstances.Count; i++)
                            {
                                var mloInstance = ymap.CMapData.MloInstances[i];

                                var mloInstanceEntry = new JObject()
                                {
                                    ["name"]     = ymap.CMapData.MloInstances[i].ArchetypeName,
                                    ["position"] = new JObject()
                                    {
                                        ["x"] = mloInstance.Position.X,
                                        ["y"] = mloInstance.Position.Y,
                                        ["z"] = mloInstance.Position.Z,
                                    },
                                    ["rotation"] = new JObject()
                                    {
                                        ["x"] = mloInstance.Rotation.X,
                                        ["y"] = mloInstance.Rotation.Y,
                                        ["z"] = mloInstance.Rotation.Z,
                                        ["w"] = mloInstance.Rotation.W,
                                    }
                                };

                                entry["mloInstances"].Add(mloInstanceEntry);
                            }
                        }

                        cache["ymap"].Add(entry);
                    }
                    else if (file.Name.EndsWith(".ytyp"))
                    {
                        var ytyp = new YtypFile();

                        using (MemoryStream ms = new MemoryStream())
                        {
                            file.Export(ms);
                            ytyp.Load(ms);
                        }

                        dynamic entry = new JObject()
                        {
                            ["name"]          = fileNameWithoutExtension,
                            ["path"]          = fullFileName,
                            ["hash"]          = Jenkins.Hash(fileNameWithoutExtension),
                            ["mloArchetypes"] = new JArray(),
                        };

                        if (ytyp.CMapTypes.MloArchetypes != null)
                        {
                            for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                            {
                                var archetype = ytyp.CMapTypes.MloArchetypes[i];
                                var mloEntry  = new JObject
                                {
                                    ["name"]  = archetype.Name,
                                    ["rooms"] = new JArray(),
                                };

                                if (archetype.Rooms != null)
                                {
                                    for (int j = 0; j < archetype.Rooms.Count; j++)
                                    {
                                        var room      = archetype.Rooms[j];
                                        var roomEntry = new JObject
                                        {
                                            ["name"]  = room.Name,
                                            ["bbMin"] = new JObject()
                                            {
                                                ["x"] = room.BbMin.X,
                                                ["y"] = room.BbMin.Y,
                                                ["z"] = room.BbMin.Z,
                                            },
                                            ["bbMax"] = new JObject()
                                            {
                                                ["x"] = room.BbMax.X,
                                                ["y"] = room.BbMax.Y,
                                                ["z"] = room.BbMax.Z,
                                            }
                                        };

                                        ((JArray)mloEntry["rooms"]).Add(roomEntry);
                                    }
                                }

                                entry["mloArchetypes"].Add(mloEntry);
                            }
                        }

                        cache["ytyp"].Add(entry);
                    }
                });

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

                File.WriteAllText(AssemblyDirectory + "\\cache.json", jsonString);

                using (StreamWriter writer = new StreamWriter(AssemblyDirectory + "\\strings.txt"))
                {
                    foreach (var kvp in Jenkins.Index)
                    {
                        writer.Write(kvp.Value + "\n");
                    }
                }
            });

            if (args.Length == 0 || args[0] == "help")
            {
                Console.Error.Write(CommandLine.GenHelp());
                return;
            }
        }
예제 #11
0
        static void HandleGenPedDefsOptions(string[] args)
        {
            CommandLine.Parse <GenPedDefsOptions>(args, (opts, gOpts) =>
            {
                var ymtRegex  = new Regex("mp_(m|f)_freemode_01.*\\.ymt$");
                var cYddRegex = new Regex("(head|berd|hair|uppr|lowr|hand|feet|teef|accs|task|decl|jbib)_(\\d\\d\\d)_u.ydd$");
                var pYddRegex = new Regex("p_(head|ears|mouth|lhand|rhand|lwrist|rwrist|hip|lfoot|rfoot)_(\\d\\d\\d).ydd$");

                var fileDlcLevels = new Dictionary <string, int>();
                var overrides     = new Dictionary <string, List <string> >();

                if (opts.CreateMode)
                {
                    if (opts.OutputDirectory == null)
                    {
                        Console.WriteLine("Please provide input directory with --output");
                        return;
                    }

                    if (!Directory.Exists(opts.OutputDirectory))
                    {
                        Directory.CreateDirectory(opts.OutputDirectory);
                    }

                    Init(args);

                    int maxDLCLevel = (Array.IndexOf(DLCList, opts.DLCLevel) == -1) ? DLCList.Length - 1 : Array.IndexOf(DLCList, opts.DLCLevel);

                    var targets   = opts.Targets?.ToList() ?? new List <string>();
                    var dlcpaths  = new Dictionary <string, int>();
                    var dlcdirs   = new Dictionary <string, int>();
                    var processed = new List <string>();

                    ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                    {
                        string[] path   = fullFileName.Split('\\');
                        string folder   = path[path.Length - 2];
                        string fileName = path[path.Length - 1];
                        string name     = fileName.Split('.').First();
                        string outPath;
                        bool isOverride = false;

                        var ymtMatch  = ymtRegex.Match(fileName);
                        var cYddMatch = cYddRegex.Match(fileName);
                        var pYddMatch = pYddRegex.Match(fileName);

                        int dlcLevel = GetDLCLevel(fullFileName);

                        if (dlcLevel > maxDLCLevel)
                        {
                            return;
                        }

                        if (targets.Count > 0 && opts.Targets.Where(e => e == name || (e + "_p") == name || e == folder || (e + "_p") == folder).ToArray().Length == 0)
                        {
                            return;
                        }

                        // Found interesting entry
                        if (ymtMatch.Success || cYddMatch.Success || pYddMatch.Success)
                        {
                            string pathPart;

                            // Found definition file (.ymt)
                            if (ymtMatch.Success)
                            {
                                if (!path[path.Length - 1].Contains("_freemode_01"))
                                {
                                    return;
                                }

                                outPath  = opts.OutputDirectory;
                                pathPart = path[path.Length - 1];

                                if (!dlcpaths.ContainsKey(pathPart))
                                {
                                    dlcpaths[pathPart] = dlcLevel;
                                    isOverride         = true;
                                }
                                else if (dlcLevel > dlcpaths[pathPart])
                                {
                                    dlcpaths[pathPart] = dlcLevel;
                                    isOverride         = true;
                                }
                            }
                            else  // Found model file (component or prop)
                            {
                                if (!path[path.Length - 2].Contains("_freemode_01"))
                                {
                                    return;
                                }

                                outPath    = opts.OutputDirectory + "\\" + path[path.Length - 2];
                                pathPart   = path[path.Length - 2] + "\\" + path[path.Length - 1];
                                string dir = path[path.Length - 2];
                                dlcLevel   = GetDLCLevel(fullFileName);

                                // Console.WriteLine(pathPart);

                                if (!dlcpaths.ContainsKey(pathPart))
                                {
                                    dlcpaths[pathPart] = dlcLevel;

                                    Console.WriteLine(DLCList[dlcLevel] + " [" + dlcLevel + "] => " + pathPart);
                                    dlcdirs[dir] = dlcLevel;
                                    isOverride   = true;
                                }
                                else if (dlcLevel > dlcdirs[dir])
                                {
                                    Console.WriteLine(DLCList[dlcLevel] + " [" + dlcLevel + "] => " + pathPart);
                                    dlcpaths[pathPart] = dlcLevel;
                                    dlcdirs[dir]       = dlcLevel;
                                    isOverride         = true;
                                }
                            }

                            Directory.CreateDirectory(outPath);

                            // If dlc level of this directory is superior to current matching one
                            if (isOverride)
                            {
                                // Write higher level ymt
                                if (ymtMatch.Success)
                                {
                                    using (var ms = new MemoryStream())
                                    {
                                        file.Export(ms);

                                        var rMeta = new ResourceFile_GTA5_pc <MetaFile>();

                                        rMeta.Load(ms);

                                        string xml = MetaXml.GetXml(rMeta.ResourceData);

                                        File.WriteAllText(outPath + "\\" + fileName + ".xml", xml);
                                    }
                                }
                                else if (cYddMatch.Success)
                                {
                                    foreach (var entry in ComponentFilePrefix)
                                    {
                                        Directory.CreateDirectory(outPath + "\\components\\" + entry.Value);
                                    }
                                }
                                else if (pYddMatch.Success)
                                {
                                    foreach (var entry in AnchorFilePrefix)
                                    {
                                        Directory.CreateDirectory(outPath + "\\props\\" + entry.Value);
                                    }
                                }

                                if (cYddMatch.Success || pYddMatch.Success)
                                {
                                    dynamic directoryInfos = new JObject();

                                    string dlc = DLCList[dlcLevel];

                                    directoryInfos["dlc"]  = dlc;
                                    directoryInfos["path"] = Directory.GetParent(fullFileName);

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

                                    File.WriteAllText(outPath + "\\directory.json", jsonString);
                                }
                            }
                        }
                    });
                }
                else
                {
                    if (opts.InputDirectory == null)
                    {
                        Console.WriteLine("Please provide input directory with --input");
                        return;
                    }

                    if (opts.OutputDirectory == null)
                    {
                        Console.WriteLine("Please provide input directory with --output");
                        return;
                    }

                    Init(args);

                    int maxDLCLevel = (Array.IndexOf(DLCList, opts.DLCLevel) == -1) ? DLCList.Length - 1 : Array.IndexOf(DLCList, opts.DLCLevel);

                    string[] files = Directory.GetFiles(opts.InputDirectory).Where(e => e.EndsWith("ymt.xml")).ToArray();
                    string[] dirs  = Directory.GetDirectories(opts.InputDirectory);
                    var addonDirs  = new List <string>();

                    var ymts = new Dictionary <string, YmtPedDefinitionFile>();

                    var processedYmts = new Dictionary <string, Tuple <
                                                            Dictionary <string, Tuple <string, int, int, int, string, string> >,
                                                            Dictionary <string, int>,
                                                            Dictionary <string, Tuple <string, int, int, int, string, string> >,
                                                            Dictionary <string, int>
                                                            > >();

                    for (int j = 0; j < files.Length; j++)
                    {
                        string targetMetaXml       = files[j];
                        string targetName          = targetMetaXml.Split('\\').Last().Replace(".ymt.xml", "");
                        string parentDirectoryPath = Directory.GetParent(targetMetaXml).FullName;
                        string parentDirectoryName = parentDirectoryPath.Split('\\').Last();

                        // Parse .ymt.xml
                        string xml = File.ReadAllText(targetMetaXml);
                        var doc    = new XmlDocument();
                        doc.LoadXml(xml);
                        var meta = XmlMeta.GetMeta(doc);
                        var ymt  = new YmtPedDefinitionFile();
                        ymt.ResourceFile.ResourceData = meta;
                        ymt.Parse();

                        ymts[targetName] = ymt;
                    }

                    if (opts.FiveMFormat)
                    {
                        Directory.CreateDirectory(opts.OutputDirectory + "\\stream");
                        File.Create(opts.OutputDirectory + "\\__resource.lua");
                    }
                    else
                    {
                        Directory.CreateDirectory(opts.OutputDirectory + "\\x64\\models\\cdimages\\streamedpeds_mp.rpf");
                        Directory.CreateDirectory(opts.OutputDirectory + "\\x64\\models\\cdimages\\streamedpedprops.rpf");

                        string contentXml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<CDataFileMgr__ContentsOfDataFileXml>
    <disabledFiles />
    <includedXmlFiles />
    <includedDataFiles />
    <dataFiles>
        <Item>
            <filename>dlc_gtauclothes:/%PLATFORM%/models/cdimages/streamedpeds_mp.rpf</filename>
            <fileType>RPF_FILE</fileType>
            <overlay value=""true"" />
            <disabled value=""true"" />
            <persistent value=""true"" />
        </Item>
        <Item>
            <filename>dlc_gtauclothes:/%PLATFORM%/models/cdimages/streamedpedprops.rpf</filename>
            <fileType>RPF_FILE</fileType>
            <overlay value=""true"" />
            <disabled value=""true"" />
            <persistent value=""true"" />
        </Item>
    </dataFiles>
    <contentChangeSets>
        <Item>
            <changeSetName>gtauclothes_AUTOGEN</changeSetName>
            <filesToDisable />
            <filesToEnable>
                <Item>dlc_gtauclothes:/%PLATFORM%/models/cdimages/streamedpeds_mp.rpf</Item>
                <Item>dlc_gtauclothes:/%PLATFORM%/models/cdimages/streamedpedprops.rpf</Item>
            </filesToEnable>
            <txdToLoad />
            <txdToUnload />
            <residentResources />
            <unregisterResources />
        </Item>
    </contentChangeSets>
    <patchFiles />
</CDataFileMgr__ContentsOfDataFileXml>";

                        string setup2Xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<SSetupData>
    <deviceName>dlc_gtauclothes</deviceName>
    <datFile>content.xml</datFile>
    <timeStamp>03/30/2018 17:26:39</timeStamp>
    <nameHash>gtauclothes</nameHash>
    <contentChangeSetGroups>
        <Item>
            <NameHash>GROUP_STARTUP</NameHash>
            <ContentChangeSets>
                <Item>gtauclothes_AUTOGEN</Item>
            </ContentChangeSets>
        </Item>
    </contentChangeSetGroups>
</SSetupData>";

                        File.WriteAllText(opts.OutputDirectory + "\\content.xml", contentXml);
                        File.WriteAllText(opts.OutputDirectory + "\\setup2.xml", setup2Xml);
                    }

                    foreach (var ymtEntry in ymts)
                    {
                        var targetName = ymtEntry.Key;
                        var ymt        = ymtEntry.Value;

                        // Components
                        var cCount        = new Dictionary <Unk_884254308, int>();
                        var cYddMapping   = new Dictionary <string, Tuple <string, int, int, int, string, string> >(); // sourceYddPath => prefix, origPos, pos, count, folder, yddFileName
                        var cTextureCount = new Dictionary <string, int>();

                        // Props
                        var pCount        = new Dictionary <Unk_2834549053, int>();
                        var pYddMapping   = new Dictionary <string, Tuple <string, int, int, int, string, string> >(); // sourceYddPath => prefix, origPos, pos, count, folder, yddFileName
                        var pTextureCount = new Dictionary <string, int>();

                        // Set component base count
                        Unk_884254308[] cValues = (Unk_884254308[])Enum.GetValues(typeof(Unk_884254308));

                        foreach (Unk_884254308 component in cValues)
                        {
                            if (component == Unk_884254308.PV_COMP_INVALID || component == Unk_884254308.PV_COMP_MAX)
                            {
                                continue;
                            }

                            cCount[component] = (ymt.Unk_376833625.Components[component] ?? new MUnk_3538495220()).Unk_1756136273.Count;
                        }

                        // Set prop base count
                        Unk_2834549053[] pValues = (Unk_2834549053[])Enum.GetValues(typeof(Unk_2834549053));

                        foreach (Unk_2834549053 anchor in pValues)
                        {
                            if (anchor == Unk_2834549053.NUM_ANCHORS)
                            {
                                continue;
                            }

                            int max = (opts.ReservePropEntries > ymt.Unk_376833625.PropInfo.Props[anchor].Count) ? opts.ReservePropEntries : ymt.Unk_376833625.PropInfo.Props[anchor].Count;

                            pCount[anchor] = (ymt.Unk_376833625.PropInfo.Props[anchor] ?? new List <MUnk_94549140>()).Count;
                        }

                        foreach (var entry in ComponentFilePrefix)
                        {
                            Unk_884254308 component = entry.Key;
                            string prefix           = entry.Value;
                            string targetDirectory  = opts.InputDirectory + "\\" + targetName + "\\components\\" + prefix;

                            if (Directory.Exists(targetDirectory))
                            {
                                IEnumerable <string> addonFilesUnordered = Directory.GetFiles(targetDirectory).Where(e => e.EndsWith(".ydd"));

                                int padLen = 0;

                                if (addonFilesUnordered.Count() > 0)
                                {
                                    padLen = addonFilesUnordered.Max(e => e.Length);
                                }

                                string[] addonFiles = addonFilesUnordered.OrderBy(e => e.PadLeft(padLen, '0')).ToArray();

                                var addons = new List <int>();

                                for (int k = 0; k < addonFiles.Length; k++)
                                {
                                    addons.Add(k);
                                }

                                if (addons.Count > 0)
                                {
                                    // Create addon component entries
                                    var def = ymt.Unk_376833625.Components[component] ?? new MUnk_3538495220();

                                    for (int k = 0; k < addons.Count; k++)
                                    {
                                        int addonPos            = def.Unk_1756136273.Count();
                                        string textureDirectory = targetDirectory + "\\" + addons[k];
                                        var addonTextures       = new List <int>();
                                        var item = new MUnk_1535046754();
                                        IEnumerable <string> texturesUnordered = Directory.GetFiles(textureDirectory).Where(e => e.EndsWith(".ytd"));
                                        int padLen1 = 0;

                                        if (texturesUnordered.Count() > 0)
                                        {
                                            padLen1 = texturesUnordered.Max(e => e.Length);
                                        }

                                        string[] textures  = texturesUnordered.OrderBy(e => e.PadLeft(padLen1, '0')).ToArray();
                                        string yddFileName = prefix + "_" + addonPos.ToString().PadLeft(3, '0') + "_u.ydd";

                                        cYddMapping[addonFiles[k]] = new Tuple <string, int, int, int, string, string>(prefix, addons[k], addonPos, addons.Count, targetDirectory, yddFileName);

                                        // Create addon texture entries
                                        for (int l = 0; l < textures.Length; l++)
                                        {
                                            addonTextures.Add(l);
                                        }

                                        cTextureCount[addonFiles[k]] = addonTextures.Count;

                                        for (int l = 0; l < addonTextures.Count; l++)
                                        {
                                            var texture = new MUnk_1036962405();
                                            item.ATexData.Add(texture);

                                            // Create componentinfo
                                            var cInfo = new MCComponentInfo();

                                            cInfo.Unk_2114993291 = 0;
                                            cInfo.Unk_3509540765 = (byte)component;
                                            cInfo.Unk_4196345791 = (byte)l;

                                            ymt.Unk_376833625.CompInfos.Add(cInfo);
                                        }

                                        if (File.Exists(addonFiles[k].Replace(".ydd", ".yld")))
                                        {
                                            item.ClothData.Unk_2828247905 = 1;
                                        }

                                        def.Unk_1756136273.Add(item);

                                        cCount[component]++;
                                    }

                                    ymt.Unk_376833625.Components[component] = def;
                                }
                            }
                        }

                        foreach (var entry in AnchorFilePrefix)
                        {
                            Unk_2834549053 anchor  = entry.Key;
                            string prefix          = entry.Value;
                            string targetDirectory = opts.InputDirectory + "\\" + targetName + "_p" + "\\props\\" + prefix;

                            if (Directory.Exists(targetDirectory))
                            {
                                IEnumerable <string> addonFilesUnordered = Directory.GetFiles(targetDirectory).Where(e => e.EndsWith(".ydd"));

                                int padLen = 0;

                                if (addonFilesUnordered.Count() > 0)
                                {
                                    padLen = addonFilesUnordered.Max(e => e.Length);
                                }

                                string[] addonFiles = addonFilesUnordered.OrderBy(e => e.PadLeft(padLen, '0')).ToArray();

                                var addons = new List <int>();

                                for (int k = 0; k < addonFiles.Length; k++)
                                {
                                    addons.Add(k);
                                }

                                if (addons.Count > 0)
                                {
                                    // Create addon prop entries
                                    var defs = ymt.Unk_376833625.PropInfo.Props[anchor] ?? new List <MUnk_94549140>();

                                    for (int k = 0; k < addons.Count; k++)
                                    {
                                        int addonPos            = defs.Count();
                                        string textureDirectory = targetDirectory + "\\" + addons[k];
                                        var addonTextures       = new List <int>();
                                        var item = new MUnk_94549140(ymt.Unk_376833625.PropInfo);
                                        IEnumerable <string> texturesUnordered = Directory.GetFiles(textureDirectory).Where(e => e.EndsWith(".ytd"));
                                        int padLen2 = 0;

                                        if (texturesUnordered.Count() > 0)
                                        {
                                            padLen2 = texturesUnordered.Max(e => e.Length);
                                        }

                                        string[] textures  = texturesUnordered.OrderBy(e => e.PadLeft(padLen2, '0')).ToArray();
                                        string yddFileName = "p_" + prefix + "_" + addonPos.ToString().PadLeft(3, '0') + ".ydd";

                                        item.AnchorId = (byte)anchor;

                                        pYddMapping[addonFiles[k]] = new Tuple <string, int, int, int, string, string>(prefix, addons[k], addonPos, addons.Count, targetDirectory, yddFileName);

                                        // Create addon texture entries
                                        for (int l = 0; l < textures.Length; l++)
                                        {
                                            addonTextures.Add(l);
                                        }

                                        pTextureCount[addonFiles[k]] = addonTextures.Count;

                                        for (int l = 0; l < addonTextures.Count; l++)
                                        {
                                            var texture = new MUnk_254518642();
                                            item.TexData.Add(texture);
                                        }

                                        // Get or create linked anchor
                                        var aanchor = ymt.Unk_376833625.PropInfo.AAnchors.Find(e => e.Anchor == anchor);

                                        if (aanchor == null)
                                        {
                                            aanchor = new MCAnchorProps(ymt.Unk_376833625.PropInfo);
                                            aanchor.PropsMap[item] = (byte)item.TexData.Count;
                                            ymt.Unk_376833625.PropInfo.AAnchors.Add(aanchor);
                                        }
                                        else
                                        {
                                            aanchor.PropsMap[item] = (byte)item.TexData.Count;
                                        }

                                        defs.Add(item);
                                        pCount[anchor]++;
                                    }

                                    ymt.Unk_376833625.PropInfo.Props[anchor] = defs;
                                }
                            }
                        }

                        // Create reserved component entries
                        foreach (Unk_884254308 component in cValues)
                        {
                            if (component == Unk_884254308.PV_COMP_INVALID || component == Unk_884254308.PV_COMP_MAX)
                            {
                                continue;
                            }

                            int count = cCount[component];
                            int max   = (opts.ReservePropEntries > count) ? opts.ReservePropEntries : count;
                            var def   = ymt.Unk_376833625.Components[component] ?? new MUnk_3538495220();

                            for (int i = count; i < max; i++)
                            {
                                var item    = new MUnk_1535046754();
                                var texture = new MUnk_1036962405();
                                item.ATexData.Add(texture);

                                // Create componentinfo
                                var cInfo = new MCComponentInfo();

                                cInfo.Unk_2114993291 = 0;
                                cInfo.Unk_3509540765 = (byte)component;
                                cInfo.Unk_4196345791 = (byte)i;

                                ymt.Unk_376833625.CompInfos.Add(cInfo);

                                def.Unk_1756136273.Add(item);
                            }

                            if (def.Unk_1756136273.Count > 0)
                            {
                                ymt.Unk_376833625.Components[component] = def;
                            }
                        }

                        // Create reserved prop entries
                        foreach (Unk_2834549053 anchor in pValues)
                        {
                            if (anchor == Unk_2834549053.NUM_ANCHORS)
                            {
                                continue;
                            }

                            int count = pCount[anchor];
                            int max   = (opts.ReservePropEntries > count) ? opts.ReservePropEntries : count;
                            var defs  = ymt.Unk_376833625.PropInfo.Props[anchor] ?? new List <MUnk_94549140>();

                            for (int i = count; i < max; i++)
                            {
                                var item      = new MUnk_94549140(ymt.Unk_376833625.PropInfo);
                                item.AnchorId = (byte)anchor;
                                var texture   = new MUnk_254518642();
                                item.TexData.Add(texture);

                                var aanchor = ymt.Unk_376833625.PropInfo.AAnchors.Find(e => e.Anchor == anchor);

                                if (aanchor == null)
                                {
                                    aanchor                = new MCAnchorProps(ymt.Unk_376833625.PropInfo);
                                    aanchor.Anchor         = anchor;
                                    aanchor.PropsMap[item] = 1;
                                    ymt.Unk_376833625.PropInfo.AAnchors.Add(aanchor);
                                }
                                else
                                {
                                    aanchor.PropsMap[item] = 1;
                                }


                                defs.Add(item);
                            }

                            if (defs.Count > 0)
                            {
                                ymt.Unk_376833625.PropInfo.Props[anchor] = defs;
                            }
                        }

                        processedYmts[targetName] = new Tuple <
                            Dictionary <string, Tuple <string, int, int, int, string, string> >,
                            Dictionary <string, int>,
                            Dictionary <string, Tuple <string, int, int, int, string, string> >,
                            Dictionary <string, int>
                            >(cYddMapping, cTextureCount, pYddMapping, pTextureCount);

                        if (opts.FiveMFormat)
                        {
                            ymt.Save(opts.OutputDirectory + "\\stream\\" + targetName + ".ymt");

                            // var xml2 = MetaXml.GetXml(ymt.ResourceFile.ResourceData);
                            // File.WriteAllText(opts.OutputDirectory + "\\stream\\" + targetMetaYmtFileName + ".xml", xml2);
                        }
                        else
                        {
                            ymt.Save(opts.OutputDirectory + "\\x64\\models\\cdimages\\streamedpeds_mp.rpf\\" + targetName + ".ymt");
                        }

                        dynamic overrideInfos = new JObject();

                        overrideInfos["components"] = new JObject();
                        overrideInfos["props"]      = new JObject();

                        foreach (Unk_884254308 component in cValues)
                        {
                            if (component == Unk_884254308.PV_COMP_INVALID || component == Unk_884254308.PV_COMP_MAX)
                            {
                                continue;
                            }

                            int count = ymt.Unk_376833625.Components[component]?.Unk_1756136273.Count ?? 0;
                            int max   = (opts.ReserveEntries > count) ? opts.ReserveEntries : count;

                            overrideInfos["components"][ComponentFilePrefix[component]] = new JObject()
                            {
                                ["start"] = cCount[component], ["end"] = max
                            };
                        }

                        foreach (Unk_2834549053 anchor in pValues)
                        {
                            if (anchor == Unk_2834549053.NUM_ANCHORS)
                            {
                                continue;
                            }

                            int count = ymt.Unk_376833625.PropInfo.Props[anchor]?.Count ?? 0;
                            int max   = (opts.ReservePropEntries > count) ? opts.ReservePropEntries : count;

                            overrideInfos["props"][AnchorFilePrefix[anchor]] = new JObject()
                            {
                                ["start"] = pCount[anchor], ["end"] = max
                            };
                        }

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

                        File.WriteAllText(opts.OutputDirectory + "\\" + targetName + ".override.json", jsonString);
                    }

                    // Check which directories contains addon component / props
                    for (int i = 0; i < dirs.Length; i++)
                    {
                        bool found = false;

                        foreach (var entry in ComponentFilePrefix)
                        {
                            string prefix = entry.Value;


                            if (Directory.Exists(dirs[i] + "\\components\\" + prefix) && Directory.GetFiles(dirs[i] + "\\components\\" + prefix).Where(e => e.EndsWith(".ydd")).Count() > 0)
                            {
                                found = true;
                                break;
                            }

                            if (Directory.Exists(dirs[i] + "\\props\\" + prefix) && Directory.GetFiles(dirs[i] + "\\props\\" + prefix).Where(e => e.EndsWith(".ydd")).Count() > 0)
                            {
                                found = true;
                                break;
                            }

                            if (found)
                            {
                                break;
                            }
                        }

                        if (found)
                        {
                            addonDirs.Add(dirs[i]);
                        }
                    }

                    for (int i = 0; i < addonDirs.Count; i++)
                    {
                        Console.WriteLine(addonDirs[i]);

                        string directory  = addonDirs[i];
                        string[] path     = directory.Split('\\');
                        string name       = path[path.Length - 1];
                        string ymtDirName = name;

                        if (ymtDirName.EndsWith("_p"))
                        {
                            ymtDirName = ymtDirName.Substring(0, ymtDirName.Length - 2);
                        }

                        Tuple <
                            Dictionary <string, Tuple <string, int, int, int, string, string> >,
                            Dictionary <string, int>,
                            Dictionary <string, Tuple <string, int, int, int, string, string> >,
                            Dictionary <string, int>
                            > processedYmtData = null;

                        // Copy models / textures with resolved names to build directory
                        if (processedYmts.TryGetValue(ymtDirName, out processedYmtData))
                        {
                            foreach (var entry in processedYmtData.Item1)
                            {
                                if (opts.FiveMFormat)
                                {
                                    GenPedDefs_CreateComponentFiles_FiveM(opts, ymtDirName, entry, processedYmtData.Item2[entry.Key]);
                                }
                                else
                                {
                                    GenPedDefs_CreateComponentFiles(opts, ymtDirName, entry, processedYmtData.Item2[entry.Key]);
                                }
                            }

                            foreach (var entry in processedYmtData.Item3)
                            {
                                if (opts.FiveMFormat)
                                {
                                    GenPedDefs_CreatePropFiles_FiveM(opts, ymtDirName, entry, processedYmtData.Item4[entry.Key]);
                                }
                                else
                                {
                                    GenPedDefs_CreatePropFiles(opts, ymtDirName, entry, processedYmtData.Item4[entry.Key]);
                                }
                            }
                        }
                    }
                }
            });
        }
예제 #12
0
        public void OnApplicationRequestOpenProject()
        {
            var ofd = new CommonOpenFileDialog();

            ofd.Title                     = "Choose Directory";
            ofd.IsFolderPicker            = true;
            ofd.AddToMostRecentlyUsedList = false;
            ofd.AllowNonFileSystemItems   = false;
            ofd.EnsureFileExists          = true;
            ofd.EnsurePathExists          = true;
            ofd.EnsureReadOnly            = false;
            ofd.EnsureValidNames          = true;
            ofd.Multiselect               = false;
            ofd.ShowPlacesList            = true;

            if (ofd.ShowDialog() == CommonFileDialogResult.Ok)
            {
                List <string> files = new List <string>(Directory.GetFiles(ofd.FileName));
                List <string> dirs  = new List <string>(Directory.GetDirectories(ofd.FileName));

                // There are directories here, so we will assume they are from already unpacked data.
                if (dirs.Count != 0)
                {
                    // Just assume the folder paths are valid now.
                    LoadProject(ofd.FileName, ofd.FileName);
                    m_sourceDataPath = ofd.FileName;
                }
                // We'll have to dump the contents of the arcs
                else
                {
                    string tempMapPath = Path.GetTempPath() + Path.GetFileName(ofd.FileName); // This is where we'll dump the arc contents to

                    if (!Directory.Exists(tempMapPath))
                    {
                        Directory.CreateDirectory(tempMapPath);
                    }

                    foreach (var arc in files)
                    {
                        VirtualFilesystemDirectory archiveRoot = ArchiveUtilities.LoadArchive(arc);
                        if (archiveRoot == null)
                        {
                            continue;
                        }

                        string tempArcPath = $"{tempMapPath}\\{archiveRoot.Name}";

                        if (!Directory.Exists(tempArcPath))
                        {
                            Directory.CreateDirectory(tempMapPath);
                        }

                        DumpContents(archiveRoot, tempArcPath);
                    }

                    LoadProject(tempMapPath, ofd.FileName);

                    // This will signal that we loaded from archives, and that there is no valid path to save the map yet.
                    MainWorld.Map.SavePath = null;
                    m_sourceDataPath       = tempMapPath;
                }
            }
        }
예제 #13
0
        private void SaveMessageArchive(string file_path)
        {
            SaveMessageData();

            ArchiveUtilities.WriteArchive(file_path, m_MessageArchive);
        }
예제 #14
0
        static void HandleFixArchiveOptions(string[] args)
        {
            CommandLine.Parse <FixArchiveOptions>(args, (opts, gOpts) =>
            {
                EnsurePath();
                EnsureKeys();

                if (opts.InputFiles != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

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

                        Console.WriteLine(fileInfo.FullName);

                        using (RageArchiveWrapper7 inputArchive = RageArchiveWrapper7.Open(fileInfo.FullName))
                        {
                            var rpfs = new List <Tuple <string, RageArchiveWrapper7> >();

                            if (opts.Recursive)
                            {
                                ArchiveUtilities.ForEachFile(fileInfo.FullName.Replace(Settings.Default.GTAFolder, ""), inputArchive.Root, inputArchive.archive_.Encryption, (string fullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
                                {
                                    if (fullFileName.EndsWith(".rpf", StringComparison.OrdinalIgnoreCase))
                                    {
                                        try
                                        {
                                            var binFile   = (RageArchiveBinaryFileWrapper7)file;
                                            var tmpStream = new FileStream(Path.GetTempFileName(), FileMode.Open);

                                            binFile.Export(tmpStream);
                                            RageArchiveWrapper7 archive = RageArchiveWrapper7.Open(tmpStream, file.Name);

                                            var wrapper = RageArchiveWrapper7.Open(tmpStream, binFile.Name);

                                            rpfs.Add(new Tuple <string, RageArchiveWrapper7>(fullFileName, wrapper));
                                        }
                                        catch (Exception e)
                                        {
                                            Console.Error.WriteLine(e.Message);
                                        }
                                    }
                                });

                                rpfs.Sort((a, b) =>
                                {
                                    return(b.Item1.Replace('\\', '/').Split('/').Length - a.Item1.Replace('\\', '/').Split('/').Length);
                                });
                            }

                            bool found = false;

                            if (opts.Recursive)
                            {
                                for (int j = 0; j < rpfs.Count; j++)
                                {
                                    var fullName = rpfs[j].Item1;
                                    var wrapper  = rpfs[j].Item2;

                                    if (wrapper.archive_.Encryption != RageArchiveEncryption7.None)
                                    {
                                        Console.WriteLine("SKIP " + fullName);
                                        continue;
                                    }

                                    found = true;

                                    wrapper.archive_.Encryption = RageArchiveEncryption7.NG;
                                    wrapper.Flush();
                                    wrapper.Dispose();

                                    Console.WriteLine("ENCRYPT " + fullName);
                                }
                            }

                            if (inputArchive.archive_.Encryption != RageArchiveEncryption7.None && !found)
                            {
                                Console.WriteLine("SKIP " + fileInfo.Name);
                                continue;
                            }

                            inputArchive.archive_.Encryption = RageArchiveEncryption7.NG;
                            inputArchive.Flush();
                            inputArchive.Dispose();

                            Console.WriteLine("ENCRYPT " + fileInfo.Name);

                            rpfs.Reverse();

                            for (int j = 0; j < rpfs.Count; j++)
                            {
                                rpfs[j].Item2.Dispose();
                            }
                        }
                    }
                }
            });
        }
예제 #15
0
        private void OnRequestImportIsland()
        {
            View.IslandImportWindow window = new View.IslandImportWindow(MainWorld.Map);
            window.FileSelector.IsFilePicker  = true;
            window.FileSelector.FileExtension = "arc";

            if (window.ShowDialog() == true)
            {
                if (window.FileName == "")
                {
                    MessageBox.Show("No filename entered!", "Island Import Error");
                    return;
                }

                if (window.SceneNumber == -1)
                {
                    MessageBox.Show("Invalid room number entered!", "Island Import Error");
                    return;
                }

                WRoom oldRoom = GetRoomFromDropdownIndex(window.SceneNumber);
                if (oldRoom != null)
                {
                    MainWorld.Map.SceneList.Remove(oldRoom);
                }

                List <WCollisionMesh> colList = oldRoom.GetChildrenOfType <WCollisionMesh>();

                if (colList.Count > 0)
                {
                    colList[0].ReleaseResources();
                }

                string tempMapPath = Path.Combine(GetStageDumpPath(), Path.GetFileName(window.FileName));

                VirtualFilesystemDirectory archiveRoot = ArchiveUtilities.LoadArchive(window.FileName);
                if (archiveRoot == null)
                {
                    MessageBox.Show("Invalid archive selected!", "Island Import Error");
                    return;
                }

                string tempArcPath = $"{tempMapPath}\\{archiveRoot.Name}";

                if (!Directory.Exists(tempArcPath))
                {
                    Directory.CreateDirectory(tempMapPath);
                }

                DumpContents(archiveRoot, tempArcPath);

                WRoom newRoom = new WRoom(MainWorld, oldRoom.RoomIndex);
                newRoom.Load(tempArcPath);
                newRoom.RoomTransform = oldRoom.RoomTransform;
                newRoom.ApplyTransformToObjects();

                newRoom.Name            = "room" + oldRoom.RoomIndex;
                archiveRoot.Name        = "room" + oldRoom.RoomIndex;
                newRoom.SourceDirectory = archiveRoot;

                MainWorld.Map.SceneList.Add(newRoom);
            }
        }
예제 #16
0
        static void HandleExtractArchiveOptions(string[] args)
        {
            CommandLine.Parse <ExtractArchiveOptions>(args, (opts, gOpts) =>
            {
                EnsurePath();
                EnsureKeys();

                if (opts.InputFile == null)
                {
                    Console.WriteLine("Please provide input archive with -i --input");
                    return;
                }

                if (opts.OutputFolder == null)
                {
                    Console.WriteLine("Please provide output folder with -o --output");
                    return;
                }

                var fileInfo   = new FileInfo(opts.InputFile);
                var fileStream = new FileStream(opts.InputFile, FileMode.Open);

                var inputArchive = RageArchiveWrapper7.Open(fileStream, fileInfo.Name);

                var queue = new List <Tuple <string, RageArchiveWrapper7, bool> >()
                {
                    new Tuple <string, RageArchiveWrapper7, bool>(fileInfo.FullName, inputArchive, false)
                };

                while (queue.Count > 0)
                {
                    var fullPath    = queue[0].Item1;
                    var rpf         = queue[0].Item2;
                    var isTmpStream = queue[0].Item3;

                    queue.RemoveAt(0);

                    ArchiveUtilities.ForEachFile(fullPath.Replace(fileInfo.FullName, ""), rpf.Root, rpf.archive_.Encryption, (string fullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
                    {
                        string path = opts.OutputFolder + fullFileName;
                        string dir  = Path.GetDirectoryName(path);

                        if (!Directory.Exists(dir))
                        {
                            Directory.CreateDirectory(dir);
                        }

                        Console.WriteLine(fullFileName);

                        if (file.Name.EndsWith(".rpf"))
                        {
                            try
                            {
                                var tmpStream = new FileStream(Path.GetTempFileName(), FileMode.Open);

                                file.Export(tmpStream);
                                RageArchiveWrapper7 archive = RageArchiveWrapper7.Open(tmpStream, file.Name);
                                queue.Add(new Tuple <string, RageArchiveWrapper7, bool>(fullFileName, archive, true));
                            }
                            catch (Exception e)
                            {
                                Console.Error.WriteLine(e.Message);
                            }
                        }
                        else
                        {
                            if (file.Name.EndsWith(".xml") || file.Name.EndsWith(".meta"))
                            {
                                byte[] data = Utils.GetBinaryFileData((IArchiveBinaryFile)file, encryption);
                                string xml;

                                if (data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF)  // Detect BOM
                                {
                                    xml = Encoding.UTF8.GetString(data, 3, data.Length - 3);
                                }
                                else
                                {
                                    xml = Encoding.UTF8.GetString(data);
                                }

                                File.WriteAllText(path, xml, Encoding.UTF8);
                            }
                            else
                            {
                                file.Export(path);
                            }
                        }
                    });

                    var stream      = (FileStream)rpf.archive_.BaseStream;
                    string fileName = stream.Name;

                    rpf.Dispose();

                    if (isTmpStream)
                    {
                        File.Delete(fileName);
                    }
                }
            });
        }
예제 #17
0
        public void OnApplicationRequestOpenProject()
        {
            var ofd = new CommonOpenFileDialog()
            {
                Title                     = "Choose Directory",
                IsFolderPicker            = true,
                AddToMostRecentlyUsedList = false,
                AllowNonFileSystemItems   = false,
                EnsureFileExists          = true,
                EnsurePathExists          = true,
                EnsureReadOnly            = false,
                EnsureValidNames          = true,
                Multiselect               = false,
                ShowPlacesList            = true
            };

            if (WSettingsManager.GetSettings().LastStagePath.FilePath != "")
            {
                ofd.InitialDirectory = WSettingsManager.GetSettings().LastStagePath.FilePath;
            }

            if (ofd.ShowDialog() == CommonFileDialogResult.Ok)
            {
                List <string> files = new List <string>(Directory.GetFiles(ofd.FileName));
                List <string> dirs  = new List <string>(Directory.GetDirectories(ofd.FileName));

                // There are directories here, and one of them is an unpacked Stage folder, so try to load all of these instead of loading the .arcs.
                if (dirs.Count != 0 && File.Exists(Path.Combine(ofd.FileName, "Stage/dzs/stage.dzs")))
                {
                    LoadProject(ofd.FileName, ofd.FileName);
                    m_sourceDataPath = ofd.FileName;
                }
                // We'll have to dump the contents of the arcs
                else
                {
                    string tempMapPath = HandleTempPath(ofd.FileName);

                    foreach (var arc in files)
                    {
                        var   filename = Path.GetFileName(arc);
                        Regex reg      = new Regex(@"(Stage|Room\d+).arc", RegexOptions.Compiled | RegexOptions.IgnoreCase);
                        if (!reg.IsMatch(filename))
                        {
                            continue;
                        }

                        VirtualFilesystemDirectory archiveRoot = ArchiveUtilities.LoadArchive(arc);
                        if (archiveRoot == null)
                        {
                            continue;
                        }

                        string tempArcPath = $"{tempMapPath}\\{archiveRoot.Name}";

                        if (!Directory.Exists(tempArcPath))
                        {
                            Directory.CreateDirectory(tempMapPath);
                        }

                        DumpContents(archiveRoot, tempArcPath);
                    }

                    LoadProject(tempMapPath, ofd.FileName);

                    // This will signal that we loaded from archives, and that there is no valid path to save the map yet.
                    MainWorld.Map.SavePath = null;
                    m_sourceDataPath       = tempMapPath;

                    WSettingsManager.GetSettings().LastStagePath.FilePath = ofd.FileName;
                    WSettingsManager.SaveSettings();
                }
            }
        }
예제 #18
0
        public void OnApplicationRequestOpenRooms()
        {
            var ofd = new CommonOpenFileDialog()
            {
                Title = "Choose Rooms to Open",
                AddToMostRecentlyUsedList = false,
                AllowNonFileSystemItems   = false,
                EnsureFileExists          = true,
                EnsurePathExists          = true,
                EnsureReadOnly            = false,
                EnsureValidNames          = true,
                Multiselect    = true,
                ShowPlacesList = true
            };

            ofd.Filters.Add(new CommonFileDialogFilter("RARC Archives", ".arc"));
            ofd.Filters.Add(new CommonFileDialogFilter("All Files", ".*"));

            if (WSettingsManager.GetSettings().LastStagePath.FilePath != "")
            {
                ofd.InitialDirectory = WSettingsManager.GetSettings().LastStagePath.FilePath;
            }

            if (ofd.ShowDialog() == CommonFileDialogResult.Ok)
            {
                List <string> files   = new List <string>(ofd.FileNames);
                string        dirPath = Path.GetDirectoryName(files[0]);

                string stageArcPath = Path.Combine(dirPath, "Stage.arc");
                if (!files.Contains(stageArcPath) && File.Exists(stageArcPath))
                {
                    // Always load the stage arc even if it wasn't selected by the user.
                    files.Add(stageArcPath);
                }

                string tempMapPath = Path.Combine(GetStageDumpPath(), Path.GetFileName(dirPath)); // This is where we'll dump the arc contents to

                DeleteDumpContentsFromTempDir();

                if (!Directory.Exists(GetStageDumpPath()))
                {
                    Directory.CreateDirectory(GetStageDumpPath());
                }

                if (!Directory.Exists(tempMapPath))
                {
                    Directory.CreateDirectory(tempMapPath);
                }

                foreach (var arc in files)
                {
                    VirtualFilesystemDirectory archiveRoot = ArchiveUtilities.LoadArchive(arc);
                    if (archiveRoot == null)
                    {
                        continue;
                    }

                    string tempArcPath = $"{tempMapPath}\\{archiveRoot.Name}";

                    if (!Directory.Exists(tempArcPath))
                    {
                        Directory.CreateDirectory(tempMapPath);
                    }

                    DumpContents(archiveRoot, tempArcPath);
                }

                LoadProject(tempMapPath, dirPath);

                // This will signal that we loaded from archives, and that there is no valid path to save the map yet.
                MainWorld.Map.SavePath = null;
                m_sourceDataPath       = tempMapPath;

                WSettingsManager.GetSettings().LastStagePath.FilePath = dirPath;
                WSettingsManager.SaveSettings();
            }
        }
예제 #19
0
        static void HandleBuildCacheOptions(string[] args)
        {
            CommandLine.Parse <BuildCacheOptions>(args, (opts, gOpts) =>
            {
                Init(args);

                dynamic cache = new JObject();

                cache["ymap"] = new JArray();
                cache["ytyp"] = new JArray();

                Console.WriteLine("Building strings");

                var names = FileUtilities.GetAllFileNamesWithoutExtension(Settings.Default.GTAFolder);

                foreach (var name in names)
                {
                    Utils.Hash(name.ToLowerInvariant().Replace("_children", ""));
                }

                using (StreamWriter writer = new StreamWriter(AssemblyDirectory + "\\strings.txt"))
                {
                    foreach (var kvp in Jenkins.Index)
                    {
                        writer.Write(kvp.Value + "\n");
                    }
                }

                Console.WriteLine("Bulding cache");

                ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                {
                    string fileNameWithoutExtension = FileUtilities.RemoveExtension(file.Name);

                    try
                    {
                        if (file.Name.EndsWith(".ymap"))
                        {
                            Console.WriteLine(fullFileName);

                            var ymap = new YmapFile();

                            using (MemoryStream ms = new MemoryStream())
                            {
                                file.Export(ms);
                                ymap.Load(ms, new object[] { true });
                            }

                            dynamic entry = new JObject()
                            {
                                ["name"]               = fileNameWithoutExtension,
                                ["path"]               = fullFileName,
                                ["hash"]               = Jenkins.Hash(fileNameWithoutExtension),
                                ["parent"]             = (uint)ymap.CMapData.Parent,
                                ["entitiesExtentsMin"] = new JObject()
                                {
                                    ["x"] = ymap.CMapData.EntitiesExtentsMin.X,
                                    ["y"] = ymap.CMapData.EntitiesExtentsMin.Y,
                                    ["z"] = ymap.CMapData.EntitiesExtentsMin.Z,
                                },
                                ["entitiesExtentsMax"] = new JObject()
                                {
                                    ["x"] = ymap.CMapData.EntitiesExtentsMax.X,
                                    ["y"] = ymap.CMapData.EntitiesExtentsMax.Y,
                                    ["z"] = ymap.CMapData.EntitiesExtentsMax.Z,
                                },
                                ["mloInstances"] = new JArray(),
                            };

                            if (ymap.CMapData.MloInstances != null)
                            {
                                for (int i = 0; i < ymap.CMapData.MloInstances.Count; i++)
                                {
                                    var mloInstance = ymap.CMapData.MloInstances[i];

                                    var mloInstanceEntry = new JObject()
                                    {
                                        ["name"]     = ymap.CMapData.MloInstances[i].ArchetypeName,
                                        ["position"] = new JObject()
                                        {
                                            ["x"] = mloInstance.Position.X,
                                            ["y"] = mloInstance.Position.Y,
                                            ["z"] = mloInstance.Position.Z,
                                        },
                                        ["rotation"] = new JObject()
                                        {
                                            ["x"] = mloInstance.Rotation.X,
                                            ["y"] = mloInstance.Rotation.Y,
                                            ["z"] = mloInstance.Rotation.Z,
                                            ["w"] = mloInstance.Rotation.W,
                                        }
                                    };

                                    entry["mloInstances"].Add(mloInstanceEntry);
                                }
                            }

                            cache["ymap"].Add(entry);
                        }
                        else if (file.Name.EndsWith(".ytyp"))
                        {
                            Console.WriteLine(fullFileName);

                            var ytyp = new YtypFile();

                            using (MemoryStream ms = new MemoryStream())
                            {
                                file.Export(ms);
                                ytyp.Load(ms);
                            }

                            dynamic entry = new JObject()
                            {
                                ["name"]          = fileNameWithoutExtension,
                                ["path"]          = fullFileName,
                                ["hash"]          = Jenkins.Hash(fileNameWithoutExtension),
                                ["mloArchetypes"] = new JArray(),
                            };

                            if (ytyp.CMapTypes.MloArchetypes != null)
                            {
                                for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                                {
                                    var archetype = ytyp.CMapTypes.MloArchetypes[i];
                                    var mloEntry  = new JObject
                                    {
                                        ["name"]  = archetype.Name,
                                        ["rooms"] = new JArray(),
                                    };

                                    if (archetype.Rooms != null)
                                    {
                                        for (int j = 0; j < archetype.Rooms.Count; j++)
                                        {
                                            var room      = archetype.Rooms[j];
                                            var roomEntry = new JObject
                                            {
                                                ["name"]  = room.Name,
                                                ["bbMin"] = new JObject()
                                                {
                                                    ["x"] = room.BbMin.X,
                                                    ["y"] = room.BbMin.Y,
                                                    ["z"] = room.BbMin.Z,
                                                },
                                                ["bbMax"] = new JObject()
                                                {
                                                    ["x"] = room.BbMax.X,
                                                    ["y"] = room.BbMax.Y,
                                                    ["z"] = room.BbMax.Z,
                                                }
                                            };

                                            ((JArray)mloEntry["rooms"]).Add(roomEntry);
                                        }
                                    }

                                    entry["mloArchetypes"].Add(mloEntry);
                                }
                            }

                            cache["ytyp"].Add(entry);
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                });

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

                File.WriteAllText(AssemblyDirectory + "\\cache.json", jsonString);
            });
        }
예제 #20
0
        private static J3D LoadModelFromResource(WActorResource.ModelResource res, string archive)
        {
            J3D j3d = null;

            if (string.IsNullOrEmpty(res.Path) || string.IsNullOrEmpty(archive))
            {
                return(null);
            }

            string archivePath = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "files", "res/Object/", archive + ".arc");

            if (!File.Exists(archivePath))
            {
                return(null);
            }

            VirtualFilesystemDirectory model_arc   = ArchiveUtilities.LoadArchive(archivePath);
            VirtualFilesystemFile      archiveFile = model_arc.GetFileAtPath(res.Path);

            if (archiveFile == null)
            {
                Console.WriteLine("LoadActorByName failed because the specified path \"{0}\" does not exist in archive \"{1}\"!", res.Path, archive);
                return(null);
            }

            byte[] j3dData = archiveFile.Data;

            j3d = new J3D(archiveFile.Name);
            using (EndianBinaryReader reader = new EndianBinaryReader(j3dData, Endian.Big))
                j3d.LoadFromStream(reader, WSettingsManager.GetSettings().DumpTextures, WSettingsManager.GetSettings().DumpShaders);

            if (res.Position != null)
            {
                j3d.SetOffsetTranslation((Vector3)res.Position);
            }
            if (res.Rotation != null)
            {
                j3d.SetOffsetRotation((Vector3)res.Rotation);
            }
            if (res.Scale != null)
            {
                j3d.SetOffsetScale((Vector3)res.Scale);
            }

            j3d.SetHardwareLight(0, m_mainLight);
            j3d.SetHardwareLight(1, m_secondaryLight);
            j3d.SetTextureOverride("ZBtoonEX", "resources/textures/ZBtoonEX.png");
            j3d.SetTextureOverride("ZAtoon", "resources/textures/ZAtoon.png");

            if (res.Animations == null)
            {
                res.Animations = new WActorResource.AnimationResource[0];
            }

            foreach (var anim in res.Animations)
            {
                VirtualFilesystemDirectory anim_arc = model_arc;

                if (!string.IsNullOrEmpty(anim.ArchiveName))
                {
                    string anim_arc_path = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "files", "res/Object/", anim.ArchiveName + ".arc");

                    if (!File.Exists(anim_arc_path))
                    {
                        return(null);
                    }

                    anim_arc = ArchiveUtilities.LoadArchive(anim_arc_path);
                }

                VirtualFilesystemFile anim_file = anim_arc.GetFileAtPath(anim.Path);

                if (anim_file == null)
                {
                    continue;
                }

                byte[] anim_data = anim_file.Data;

                // Decompress the file if necessary
                if (anim_data[0] == 'Y')
                {
                    MemoryStream decompressed_data = null;

                    using (EndianBinaryReader decompressor = new EndianBinaryReader(anim_data, Endian.Big))
                    {
                        decompressed_data = Yaz0.Decode(decompressor);
                    }

                    anim_data = decompressed_data.ToArray();
                }

                switch (anim.Type)
                {
                case "bck":
                    BCK loaded_bck = new BCK(anim_file.Name);
                    using (EndianBinaryReader reader = new EndianBinaryReader(anim_data, Endian.Big))
                        loaded_bck.LoadFromStream(reader);

                    j3d.BoneAnimations.Add(loaded_bck);
                    j3d.SetBoneAnimation(anim_file.Name);

                    loaded_bck.Tick(anim.StartTime);

                    if (anim.PausedOnLoad)
                    {
                        loaded_bck.Pause();
                    }
                    break;

                case "btk":
                    BTK loaded_btk = new BTK(anim_file.Name);
                    using (EndianBinaryReader reader = new EndianBinaryReader(anim_data, Endian.Big))
                        loaded_btk.LoadFromStream(reader);

                    j3d.MaterialAnimations.Add(loaded_btk);
                    j3d.SetMaterialAnimation(anim_file.Name);

                    loaded_btk.Tick(anim.StartTime);

                    if (anim.PausedOnLoad)
                    {
                        loaded_btk.Pause();
                    }
                    break;

                case "brk":
                    BRK loaded_brk = new BRK(anim_file.Name);
                    using (EndianBinaryReader reader = new EndianBinaryReader(anim_data, Endian.Big))
                        loaded_brk.LoadFromStream(reader);

                    j3d.RegisterAnimations.Add(loaded_brk);
                    j3d.SetRegisterAnimation(anim_file.Name);

                    loaded_brk.Tick(anim.StartTime);

                    if (anim.PausedOnLoad)
                    {
                        loaded_brk.Pause();
                    }
                    break;

                case "bmt":
                    BMT loaded_bmt = new BMT(anim_file.Name);
                    using (EndianBinaryReader reader = new EndianBinaryReader(anim_data, Endian.Big))
                        loaded_bmt.LoadFromStream(reader);

                    j3d.ExternalMaterials.Add(loaded_bmt);
                    j3d.SetExternalMaterial(anim_file.Name);

                    if (loaded_bmt.MAT3 != null)
                    {
                        // a hack to get bmts working
                        Material dummyMat = null;
                        j3d.AssignVertexAttributesToMaterialsRecursive(j3d.INF1Tag.HierarchyRoot, ref dummyMat, loaded_bmt.MAT3);
                        j3d.GenerateShadersForMaterials(loaded_bmt.MAT3);
                    }

                    break;

                default:
                    break;
                }
            }

            j3d.Tick(1 / (float)60);

            if (res.ChildModels == null)
            {
                res.ChildModels = new WActorResource.ModelResource[0];
            }

            foreach (var childRes in res.ChildModels)
            {
                var childJ3d = LoadModelFromResource(childRes, archive);
                j3d.AddChildModel(childJ3d, childRes.ParentJointName);
            }

            return(j3d);
        }
예제 #21
0
        public static string[] GetDLCList()
        {
            Console.Error.WriteLine("Loading DLC list");

            var orderRegex    = new Regex("<order value=\"(\\d*)\"");
            var minOrderRegex = new Regex("<minOrder value=\"(\\d*)\"");
            var pathRegex     = new Regex(@"\\dlcpacks\\([a-z0-9_]*)\\");
            var pathRegex2    = new Regex(@"\\dlc_patch\\([a-z0-9_]*)\\");

            var dlclist   = new List <string>();
            var dlcOrders = new Dictionary <string, Tuple <int, int> >()
            {
                { "default", new Tuple <int, int>(0, 0) }
            };
            var fileName     = Settings.Default.GTAFolder + "\\update\\update.rpf";
            var fileInfo     = new FileInfo(fileName);
            var fileStream   = new FileStream(fileName, FileMode.Open);
            var inputArchive = RageArchiveWrapper7.Open(fileStream, fileInfo.Name);
            var doc          = new XmlDocument();

            ArchiveUtilities.ForEachFile(fileName.Replace(Settings.Default.GTAFolder, ""), inputArchive.Root, inputArchive.archive_.Encryption, (string fullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
            {
                if (fullFileName.EndsWith("dlclist.xml"))
                {
                    byte[] data = Utils.GetBinaryFileData((IArchiveBinaryFile)file, encryption);
                    string xml;

                    if (data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF)  // Detect BOM
                    {
                        xml = Encoding.UTF8.GetString(data, 3, data.Length - 3);
                    }
                    else
                    {
                        xml = Encoding.UTF8.GetString(data);
                    }

                    doc.LoadXml(xml);
                }
            });

            inputArchive.Dispose();


            ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (string fullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
            {
                if (fullFileName.EndsWith("setup2.xml") && !fullFileName.StartsWith("\\mods"))
                {
                    byte[] data = Utils.GetBinaryFileData((IArchiveBinaryFile)file, encryption);
                    string xml;

                    if (data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF)  // Detect BOM
                    {
                        xml = Encoding.UTF8.GetString(data, 3, data.Length - 3);
                    }
                    else
                    {
                        xml = Encoding.UTF8.GetString(data);
                    }

                    var matchOrder    = orderRegex.Match(xml);
                    var matchMinOrder = minOrderRegex.Match(xml);
                    var matchPath     = pathRegex.Match(fullFileName);
                    var matchPath2    = pathRegex2.Match(fullFileName);

                    var dlcName = matchPath.Success ? matchPath.Groups[1].Value : matchPath2.Groups[1].Value;

                    dlcOrders[dlcName] = new Tuple <int, int>(matchOrder.Success ? int.Parse(matchOrder.Groups[1].Value) : 0, matchMinOrder.Success ? int.Parse(matchMinOrder.Groups[1].Value) : 0);
                }
            });

            foreach (XmlNode pathsnode in doc.DocumentElement)
            {
                foreach (XmlNode itemnode in pathsnode.ChildNodes)
                {
                    string   p    = itemnode.InnerText.ToLowerInvariant();
                    string[] path = p.Split('/');

                    if (path.Length - 2 < 0)
                    {
                        Console.Error.WriteLine("Ignoring " + p);
                    }
                    else
                    {
                        dlclist.Add(path[path.Length - 2]);
                    }
                }
            }

            var kvp  = new List <KeyValuePair <string, Tuple <int, int> > >(); // dlc name => order, minOrder
            var list = new List <string>();

            foreach (var entry in dlcOrders)
            {
                kvp.Add(entry);
            }

            kvp.Sort((a, b) => {
                int test = a.Value.Item1 - b.Value.Item1;

                if (test == 0)
                {
                    return(dlclist.IndexOf(a.Key) - dlclist.IndexOf(b.Key));
                }
                else
                {
                    return(test);
                }
            });

            for (int i = 0; i < kvp.Count; i++)
            {
                list.Add(kvp[i].Key);
            }

            return(list.ToArray());
        }
예제 #22
0
        // 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);
            });
        }
예제 #23
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);
                    }
                }
            });
        }
예제 #24
0
        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");
                    }
                }
            });
        }
예제 #25
0
        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("");
                    }
                });
            });
        }
예제 #26
0
        static void Main(string[] args)
        {
            GTA5Constants.LoadFromPath(".");

            string GTAVDir = args[0];

            HashEmbeddedStrings();
            SaveMetaNames();

            var sbe   = new StringBuilder();
            var sbs   = new StringBuilder();
            var sbei  = new StringBuilder();
            var sbsi  = new StringBuilder();
            var sbmt  = new StringBuilder();
            var sbsei = new StringBuilder();
            var sbsci = new StringBuilder();

            sbe.AppendLine("\t// Enums\n");
            sbs.AppendLine("\t// Structures\n");

            Console.CancelKeyPress += new ConsoleCancelEventHandler((s, e) =>
            {
                Console.Error.WriteLine("Generating structure and enum infos for gathered data");

                GenerateStructureData(sbs, sbsi);
                GenerateEnumData(sbei);
                GenerateStructureEnumInfos(sbsei);

                var _data = CompileData(sbmt, sbei, sbsi, sbe, sbs, sbsei, sbsci);

                File.WriteAllText("MetaTypes.cs", _data);

                Environment.Exit(0);
            });

            ArchiveUtilities.ForEachFile(GTAVDir, (fullName, file, encryption) =>
            {
                if (/*file.Name.EndsWith(".ymap") || file.Name.EndsWith(".ytyp") || */ file.Name.EndsWith(".ymt") && Regex.Match(file.Name, @"mp_m_freemode_01.*\.ymt").Success)
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        file.Export(ms);

                        try
                        {
                            var res = new ResourceFile_GTA5_pc <MetaFile>();

                            res.Load(ms);

                            var meta = res.ResourceData;

                            GetEnums(meta, Enums, sbe);
                            GetStructures(meta, Structures);
                        }
                        catch (Exception e)
                        {
                        }
                    }
                }

                if (/*file.Name.EndsWith(".ymap") || file.Name.EndsWith(".ytyp") || */ file.Name.EndsWith(".ymt"))
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        file.Export(ms);

                        try
                        {
                            var res = new ResourceFile_GTA5_pc <MetaFile>();

                            res.Load(ms);

                            var meta = res.ResourceData;

                            GetEnums(meta, Enums, sbe);
                            GetStructures(meta, Structures);
                        }
                        catch (Exception e)
                        {
                        }
                    }
                }
            });

            Console.Error.WriteLine("Generating structure and enum infos for gathered data");

            GenerateStructureData(sbs, sbsi);
            GenerateEnumData(sbei);
            GenerateStructureEnumInfos(sbsei);

            var data = CompileData(sbmt, sbei, sbsi, sbe, sbs, sbsei, sbsci);

            File.WriteAllText("MetaTypes.cs", data);
        }
예제 #27
0
        public static J3D LoadActorByName(string actorName)
        {
            // Stop to check if we've already loaded this model.
            var existRef = m_j3dList.Find(x => string.Compare(x.FilePath, actorName, StringComparison.InvariantCultureIgnoreCase) == 0);

            if (existRef != null)
            {
                existRef.ReferenceCount++;
                return(existRef.Asset);
            }

            if (actorName == null)
            {
                return(null);
            }

            // Check to see if we have an Actor Descriptor for this actor.
            if (!m_actorDescriptors.ContainsKey(actorName))
            {
                return(null);
            }

            WActorDescriptor descriptor = m_actorDescriptors[actorName];

            // Check to see that this actor descriptor specifies a model path.
            if (string.IsNullOrEmpty(descriptor.ModelPath) || string.IsNullOrEmpty(descriptor.ArchiveName))
            {
                return(null);
            }

            string archivePath = Path.Combine(Properties.Settings.Default.RootDirectory, "res/Object/", descriptor.ArchiveName + ".arc");

            // Check to see that the archive exists
            if (!File.Exists(archivePath))
            {
                return(null);
            }

            // Finally, open the archive so we can look insdie of it to see if it exists.
            VirtualFilesystemDirectory archive     = ArchiveUtilities.LoadArchive(archivePath);
            VirtualFilesystemFile      archiveFile = archive.GetFileAtPath(descriptor.ModelPath);

            if (archiveFile == null)
            {
                Console.WriteLine("LoadActorByName failed because the specified path \"{0}\" does not exist in archive \"{1}\"!", descriptor.ModelPath, descriptor.ArchiveName);
                return(null);
            }

            // Now that we finally have the file, we can try to load a J3D from it.
            byte[] j3dData = archiveFile.Data;

            J3D j3d = new J3D(archiveFile.Name);

            using (EndianBinaryReader reader = new EndianBinaryReader(j3dData, Endian.Big))
                j3d.LoadFromStream(reader, Properties.Settings.Default.DumpTexturesToDisk, Properties.Settings.Default.DumpShadersToDisk);

            j3d.SetHardwareLight(0, m_mainLight);
            j3d.SetHardwareLight(1, m_secondaryLight);

            // Apply patches for Wind Waker by default, since they don't seem to break anything else.
            j3d.SetTextureOverride("ZBtoonEX", "resources/textures/ZBtoonEX.png");
            j3d.SetTextureOverride("ZAtoon", "resources/textures/ZAtoon.png");
            j3d.SetColorWriteOverride("eyeLdamA", false);
            j3d.SetColorWriteOverride("eyeLdamB", false);
            j3d.SetColorWriteOverride("mayuLdamA", false);
            j3d.SetColorWriteOverride("mayuLdamB", false);
            j3d.SetColorWriteOverride("eyeRdamA", false);
            j3d.SetColorWriteOverride("eyeRdamB", false);
            j3d.SetColorWriteOverride("mayuRdamA", false);
            j3d.SetColorWriteOverride("mayuRdamB", false);

            existRef          = new TSharedRef <J3D>();
            existRef.FilePath = actorName;
            existRef.Asset    = j3d;
            existRef.ReferenceCount++;

            m_j3dList.Add(existRef);

            return(j3d);
        }