public IGameDataEntry GetEntry(string name) { var file = m_directory.GetFile(name); if (file != null) { if (file.Name.EndsWith(".rpf")) { var binaryFile = (IArchiveBinaryFile)file; return(new ArchiveDirectoryEntry(RageArchiveWrapper7.Open(binaryFile.GetStream(), binaryFile.Name).Root, binaryFile.Name)); } return(new ArchiveFileEntry(file)); } var directory = m_directory.GetDirectory(name); if (directory != null) { return(new ArchiveDirectoryEntry(directory)); } throw new FileNotFoundException(); }
/// <summary> /// Opens an archive. /// </summary> public void Load(string fileName) { // close first... Close(); this.archive = RageArchiveWrapper7.Open(fileName); this.fileName = fileName; }
/// <summary> /// Creates an archive. /// </summary> public void New(string fileName) { // close first... Close(); this.archive = RageArchiveWrapper7.Create(fileName); this.fileName = fileName; }
private void RebuildArchive(string sourceArchiveFileName, string destinationArchiveFileName) { var fileInfo = new FileInfo(sourceArchiveFileName); var fileStream = new FileStream(sourceArchiveFileName, FileMode.Open); var sourceArchive = RageArchiveWrapper7.Open(fileStream, fileInfo.Name); var destinationArchive = RageArchiveWrapper7.Create(destinationArchiveFileName); RebuildDictionary(sourceArchive.Root, destinationArchive.Root, sourceArchive.archive_.Encryption); destinationArchive.FileName = fileInfo.Name; destinationArchive.archive_.Encryption = sourceArchive.archive_.Encryption; destinationArchive.Flush(); }
public static ArchiveDirectoryEntry GetFromCache(string path) { if (ms_archiveCache.TryGetValue(path, out var value)) { return(value); } var entry = new ArchiveDirectoryEntry(RageArchiveWrapper7.Open(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read), Path.GetFileName(path)).Root, Path.GetFileName(path)); ms_archiveCache.Add(path, entry); return(entry); }
public static void ForEachFile(string gameDirectoryName, ProcessFileDelegate processDelegate) { var archiveFileNames = Directory.GetFiles(gameDirectoryName, "*.rpf", SearchOption.AllDirectories); for (int i = 0; i < archiveFileNames.Length; i++) { var fileName = archiveFileNames[i]; var fileInfo = new FileInfo(fileName); var fileStream = new FileStream(fileName, FileMode.Open); var inputArchive = RageArchiveWrapper7.Open(fileStream, fileInfo.Name); ForEachFile(fileName.Replace(gameDirectoryName, ""), inputArchive.Root, inputArchive.archive_.Encryption, processDelegate); inputArchive.Dispose(); } }
private void RebuildArchiveFile(IArchiveBinaryFile sourceFile, IArchiveDirectory destinationDirectory) { var fileStream = sourceFile.GetStream(); var inputArchive = RageArchiveWrapper7.Open(fileStream, sourceFile.Name); var newF = destinationDirectory.CreateBinaryFile(); newF.Name = sourceFile.Name; var outStream = newF.GetStream(); var outputArchive = RageArchiveWrapper7.Create(outStream, sourceFile.Name); RebuildDictionary(inputArchive.Root, outputArchive.Root, inputArchive.archive_.Encryption); outputArchive.FileName = sourceFile.Name; outputArchive.archive_.Encryption = inputArchive.archive_.Encryption; outputArchive.Flush(); }
private static void ForEachFile(string fullPathName, IArchiveDirectory directory, RageArchiveEncryption7 encryption, ProcessFileDelegate processDelegate) { foreach (var file in directory.GetFiles()) { processDelegate(fullPathName + "\\" + file.Name, file, encryption); if ((file is IArchiveBinaryFile) && file.Name.EndsWith(".rpf", StringComparison.OrdinalIgnoreCase)) { var fileStream = ((IArchiveBinaryFile)file).GetStream(); var inputArchive = RageArchiveWrapper7.Open(fileStream, file.Name); ForEachFile(fullPathName + "\\" + file.Name, inputArchive.Root, inputArchive.archive_.Encryption, processDelegate); } } foreach (var subDirectory in directory.GetDirectories()) { ForEachFile(fullPathName + "\\" + subDirectory.Name, subDirectory, encryption, processDelegate); } }
public static void ForEachFile(string gameDirectoryName, ProcessFileDelegate processDelegate, ErrorDelegate errorDelegate = null) { var archiveFileNames = Directory.GetFiles(gameDirectoryName, "*.rpf", SearchOption.AllDirectories); for (int i = 0; i < archiveFileNames.Length; i++) { try { var fileName = archiveFileNames[i]; var inputArchive = RageArchiveWrapper7.Open(fileName); ForEachFile(fileName.Replace(gameDirectoryName, ""), inputArchive.Root, inputArchive.archive_.Encryption, processDelegate); inputArchive.Dispose(); } catch (Exception e) { errorDelegate?.Invoke(e); } } }
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); } }
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()); }
internal RageArchiveResourceFileWrapper7(RageArchiveWrapper7 archiveWrapper, RageArchiveResourceFile7 file) { this.archiveWrapper = archiveWrapper; this.file = file; }
public static void BuildResourceSingle(string outputFolder, string collectionName) { Utils.EnsureKeys(); using (RageArchiveWrapper7 rpf = RageArchiveWrapper7.Create(outputFolder + @"\dlc.rpf")) { rpf.archive_.Encryption = RageArchiveEncryption7.NG; var dir = rpf.Root.CreateDirectory(); dir.Name = "common"; var dataDir = dir.CreateDirectory(); dataDir.Name = "data"; dir = rpf.Root.CreateDirectory(); dir.Name = "x64"; dir = dir.CreateDirectory(); dir.Name = "models"; var cdimagesDir = dir.CreateDirectory(); cdimagesDir.Name = "cdimages"; RageArchiveWrapper7 currComponentRpf = null; IArchiveDirectory currComponentDir = null; RageArchiveWrapper7 currPropRpf = null; IArchiveDirectory currPropDir = null; bool hasMale = false; bool hasFemale = false; bool hasMaleProps = false; bool hasFemaleProps = false; for (int sexNr = 0; sexNr < 2; ++sexNr) { //Male YMT generating YmtPedDefinitionFile ymt = new YmtPedDefinitionFile { metaYmtName = Prefixes[sexNr] + collectionName, Unk_376833625 = { DlcName = RageLib.Hash.Jenkins.Hash(Prefixes[sexNr] + collectionName) } }; MUnk_3538495220[] componentTextureBindings = { null, null, null, null, null, null, null, null, null, null, null, null }; int[] componentIndexes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int[] propIndexes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //ymt.Unk_376833625.Unk_1235281004 = 0; //ymt.Unk_376833625.Unk_4086467184 = 0; //ymt.Unk_376833625.Unk_911147899 = 0; //ymt.Unk_376833625.Unk_315291935 = 0; //ymt.Unk_376833625.Unk_2996560424 = ; bool isAnyClothAdded = false; bool isAnyPropAdded = false; foreach (ClothData clothData in MainWindow.Clothes) { if (clothData.IsComponent()) { if (clothData.Textures.Count <= 0 || (int)clothData.TargetSex != sexNr) { continue; } var componentItemInfo = GenerateYmtPedComponentItem(clothData, ref componentTextureBindings); ymt.Unk_376833625.CompInfos.Add(componentItemInfo); var componentTypeId = componentItemInfo.Unk_3509540765; GetClothPostfixes(clothData, out var ytdPostfix, out var yddPostfix); if (!isAnyClothAdded) { isAnyClothAdded = true; var ms = new MemoryStream(); currComponentRpf = RageArchiveWrapper7.Create(ms, FolderNames[sexNr].Replace("ped_", collectionName + "_") + ".rpf"); currComponentRpf.archive_.Encryption = RageArchiveEncryption7.NG; currComponentDir = currComponentRpf.Root.CreateDirectory(); currComponentDir.Name = Prefixes[sexNr] + "freemode_01_" + Prefixes[sexNr] + collectionName; } int currentComponentIndex = componentIndexes[componentTypeId]++; string componentNumerics = currentComponentIndex.ToString().PadLeft(3, '0'); string prefix = clothData.GetPrefix(); clothData.SetComponentNumerics(componentNumerics, currentComponentIndex); var resource = currComponentDir.CreateResourceFile(); resource.Name = prefix + "_" + componentNumerics + "_" + yddPostfix + ".ydd"; resource.Import(clothData.MainPath); char offsetLetter = 'a'; for (int i = 0; i < clothData.Textures.Count; ++i) { resource = currComponentDir.CreateResourceFile(); resource.Name = prefix + "_diff_" + componentNumerics + "_" + (char)(offsetLetter + i) + "_" + ytdPostfix + ".ytd"; resource.Import(clothData.Textures[i]); } if (clothData.FirstPersonModelPath != "") { resource = currComponentDir.CreateResourceFile(); resource.Name = prefix + "_" + componentNumerics + "_" + yddPostfix + "_1.ydd"; resource.Import(clothData.FirstPersonModelPath); } } else { if (clothData.Textures.Count <= 0 || (int)clothData.TargetSex != sexNr) { continue; } Unk_2834549053 anchor = (Unk_2834549053)clothData.GetPedPropTypeId(); var defs = ymt.Unk_376833625.PropInfo.Props[anchor] ?? new List <MUnk_94549140>(); var item = GenerateYmtPedPropItem(ymt, anchor, clothData); defs.Add(item); if (!isAnyPropAdded) { isAnyPropAdded = true; var ms = new MemoryStream(); currPropRpf = RageArchiveWrapper7.Create(ms, FolderNames[sexNr].Replace("ped_", collectionName + "_") + "_p.rpf"); currPropRpf.archive_.Encryption = RageArchiveEncryption7.NG; currPropDir = currPropRpf.Root.CreateDirectory(); currPropDir.Name = Prefixes[sexNr] + "freemode_01_p_" + Prefixes[sexNr] + collectionName; } int currentPropIndex = propIndexes[(byte)anchor]++; string componentNumerics = currentPropIndex.ToString().PadLeft(3, '0'); string prefix = clothData.GetPrefix(); clothData.SetComponentNumerics(componentNumerics, currentPropIndex); var resource = currPropDir.CreateResourceFile(); resource.Name = prefix + "_" + componentNumerics + ".ydd"; resource.Import(clothData.MainPath); char offsetLetter = 'a'; for (int i = 0; i < clothData.Textures.Count; ++i) { resource = currPropDir.CreateResourceFile(); resource.Name = prefix + "_diff_" + componentNumerics + "_" + (char)(offsetLetter + i) + ".ytd"; resource.Import(clothData.Textures[i]); } } } if (isAnyClothAdded) { if (sexNr == 0) { hasMale = true; } else if (sexNr == 1) { hasFemale = true; } UpdateYmtComponentTextureBindings(componentTextureBindings, ymt); } if (isAnyClothAdded || isAnyPropAdded) { using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(GenerateShopMeta((Sex)sexNr, collectionName)))) { var binFile = dataDir.CreateBinaryFile(); binFile.Name = Prefixes[sexNr] + "freemode_01_" + Prefixes[sexNr] + collectionName + ".meta"; binFile.Import(stream); } currComponentRpf.Flush(); var binRpfFile = cdimagesDir.CreateBinaryFile(); binRpfFile.Name = FolderNames[sexNr].Replace("ped_", collectionName + "_") + ".rpf"; binRpfFile.Import(currComponentRpf.archive_.BaseStream); currComponentRpf.Dispose(); } if (isAnyPropAdded) { if (sexNr == 0) { hasMaleProps = true; } else if (sexNr == 1) { hasFemaleProps = true; } currPropRpf.Flush(); var binRpfFile = cdimagesDir.CreateBinaryFile(); binRpfFile.Name = FolderNames[sexNr].Replace("ped_", collectionName + "_") + "_p.rpf"; binRpfFile.Import(currPropRpf.archive_.BaseStream); currPropRpf.Dispose(); } } using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(GenerateSingleplayerContentXml(collectionName, hasMale, hasFemale, hasMaleProps, hasFemaleProps)))) { var binFile = rpf.Root.CreateBinaryFile(); binFile.Name = "content.xml"; binFile.Import(stream); } using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(GenerateSingleplayerSetup2Xml(collectionName)))) { var binFile = rpf.Root.CreateBinaryFile(); binFile.Name = "setup2.xml"; binFile.Import(stream); } rpf.Flush(); rpf.Dispose(); } }
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(); } } } } }); }
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); } } }); }
public static void BuildResourceSingle(string outputFolder, string collectionName) { Utils.EnsureKeys(); using (RageArchiveWrapper7 rpf = RageArchiveWrapper7.Create(outputFolder + @"\dlc.rpf")) { rpf.archive_.Encryption = RageArchiveEncryption7.NG; var dir = rpf.Root.CreateDirectory(); dir.Name = "common"; var dataDir = dir.CreateDirectory(); dataDir.Name = "data"; dir = rpf.Root.CreateDirectory(); dir.Name = "x64"; dir = dir.CreateDirectory(); dir.Name = "models"; var cdimagesDir = dir.CreateDirectory(); cdimagesDir.Name = "cdimages"; RageArchiveWrapper7 currComponentRpf = null; IArchiveDirectory currComponentDir = null; RageArchiveWrapper7 currPropRpf = null; IArchiveDirectory currPropDir = null; bool hasMale = false; bool hasFemale = false; bool hasMaleProps = false; bool hasFemaleProps = false; for (int sexNr = 0; sexNr < 2; ++sexNr) { //Male YMT generating YmtPedDefinitionFile ymt = new YmtPedDefinitionFile(); ymt.metaYmtName = prefixes[sexNr] + collectionName; ymt.Unk_376833625.DlcName = RageLib.Hash.Jenkins.Hash(prefixes[sexNr] + collectionName); MUnk_3538495220[] componentTextureBindings = { null, null, null, null, null, null, null, null, null, null, null, null }; int[] componentIndexes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int[] propIndexes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //ymt.Unk_376833625.Unk_1235281004 = 0; //ymt.Unk_376833625.Unk_4086467184 = 0; //ymt.Unk_376833625.Unk_911147899 = 0; //ymt.Unk_376833625.Unk_315291935 = 0; //ymt.Unk_376833625.Unk_2996560424 = ; bool isAnyClothAdded = false; bool isAnyPropAdded = false; foreach (ClothData cd in MainWindow.clothes) { if (cd.IsComponent()) { byte componentTypeID = cd.GetComponentTypeID(); if (cd.textures.Count > 0 && (int)cd.targetSex == sexNr) { YmtPedDefinitionFile targetYmt = ymt; if (componentTextureBindings[componentTypeID] == null) { componentTextureBindings[componentTypeID] = new MUnk_3538495220(); } MUnk_1535046754 textureDescription = new MUnk_1535046754(); byte nextPropMask = 17; switch (componentTypeID) { case 2: case 7: nextPropMask = 11; break; case 5: case 8: nextPropMask = 65; break; case 9: nextPropMask = 1; break; case 10: nextPropMask = 5; break; case 11: nextPropMask = 1; break; default: break; } textureDescription.PropMask = nextPropMask; textureDescription.Unk_2806194106 = (byte)(cd.fpModelPath != "" ? 1 : 0); byte texId = (byte)(cd.mainPath.EndsWith("_u.ydd") ? 0 : 1); string postfix = cd.mainPath.EndsWith("_u.ydd") ? "u" : "r"; string ytdPostfix = cd.mainPath.EndsWith("_u.ydd") ? "uni" : "whi"; foreach (string texPath in cd.textures) { MUnk_1036962405 texInfo = new MUnk_1036962405(); texInfo.Distribution = 255; texInfo.TexId = texId; textureDescription.ATexData.Add(texInfo); } textureDescription.ClothData.Unk_2828247905 = 0; componentTextureBindings[componentTypeID].Unk_1756136273.Add(textureDescription); byte componentTextureLocalId = (byte)(componentTextureBindings[componentTypeID].Unk_1756136273.Count - 1); MCComponentInfo componentInfo = new MCComponentInfo(); componentInfo.Unk_802196719 = 0; componentInfo.Unk_4233133352 = 0; componentInfo.Unk_128864925.b0 = (byte)(cd.componentFlags.unkFlag1 ? 1 : 0); componentInfo.Unk_128864925.b1 = (byte)(cd.componentFlags.unkFlag2 ? 1 : 0); componentInfo.Unk_128864925.b2 = (byte)(cd.componentFlags.unkFlag3 ? 1 : 0); componentInfo.Unk_128864925.b3 = (byte)(cd.componentFlags.unkFlag4 ? 1 : 0); componentInfo.Unk_128864925.b4 = (byte)(cd.componentFlags.isHighHeels ? 1 : 0); componentInfo.Flags = 0; componentInfo.Inclusions = 0; componentInfo.Exclusions = 0; componentInfo.Unk_1613922652 = 0; componentInfo.Unk_2114993291 = 0; componentInfo.Unk_3509540765 = componentTypeID; componentInfo.Unk_4196345791 = componentTextureLocalId; targetYmt.Unk_376833625.CompInfos.Add(componentInfo); if (!isAnyClothAdded) { isAnyClothAdded = true; var ms = new MemoryStream(); currComponentRpf = RageArchiveWrapper7.Create(ms, folderNames[sexNr].Replace("ped_", collectionName + "_") + ".rpf"); currComponentRpf.archive_.Encryption = RageArchiveEncryption7.NG; currComponentDir = currComponentRpf.Root.CreateDirectory(); currComponentDir.Name = prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName; } int currentComponentIndex = componentIndexes[componentTypeID]++; string componentNumerics = currentComponentIndex.ToString().PadLeft(3, '0'); string prefix = cd.GetPrefix(); var resource = currComponentDir.CreateResourceFile(); resource.Name = prefix + "_" + componentNumerics + "_" + postfix + ".ydd"; resource.Import(cd.mainPath); char offsetLetter = 'a'; for (int i = 0; i < cd.textures.Count; ++i) { resource = currComponentDir.CreateResourceFile(); resource.Name = prefix + "_diff_" + componentNumerics + "_" + (char)(offsetLetter + i) + "_" + ytdPostfix + ".ytd"; resource.Import(cd.textures[i]); } if (cd.fpModelPath != "") { resource = currComponentDir.CreateResourceFile(); resource.Name = prefix + "_" + componentNumerics + "_" + postfix + "_1.ydd"; resource.Import(cd.fpModelPath); } } } else { Unk_2834549053 anchor = (Unk_2834549053)cd.GetPedPropTypeID(); if (cd.textures.Count > 0 && (int)cd.targetSex == sexNr) { YmtPedDefinitionFile targetYmt = ymt; var defs = ymt.Unk_376833625.PropInfo.Props[anchor] ?? new List <MUnk_94549140>(); var item = new MUnk_94549140(ymt.Unk_376833625.PropInfo); item.AnchorId = (byte)anchor; for (int i = 0; i < cd.textures.Count; i++) { var texture = new MUnk_254518642(); texture.TexId = (byte)i; 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) { Anchor = anchor }; 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); if (!isAnyPropAdded) { isAnyPropAdded = true; var ms = new MemoryStream(); currPropRpf = RageArchiveWrapper7.Create(ms, folderNames[sexNr].Replace("ped_", collectionName + "_") + "_p.rpf"); currPropRpf.archive_.Encryption = RageArchiveEncryption7.NG; currPropDir = currPropRpf.Root.CreateDirectory(); currPropDir.Name = prefixes[sexNr] + "freemode_01_p_" + prefixes[sexNr] + collectionName; } int currentPropIndex = propIndexes[(byte)anchor]++; string componentNumerics = currentPropIndex.ToString().PadLeft(3, '0'); string prefix = cd.GetPrefix(); var resource = currPropDir.CreateResourceFile(); resource.Name = prefix + "_" + componentNumerics + ".ydd"; resource.Import(cd.mainPath); char offsetLetter = 'a'; for (int i = 0; i < cd.textures.Count; ++i) { resource = currPropDir.CreateResourceFile(); resource.Name = prefix + "_diff_" + componentNumerics + "_" + (char)(offsetLetter + i) + ".ytd"; resource.Import(cd.textures[i]); } } } } if (isAnyClothAdded) { if (sexNr == 0) { hasMale = true; } else if (sexNr == 1) { hasFemale = true; } int arrIndex = 0; for (int i = 0; i < componentTextureBindings.Length; ++i) { if (componentTextureBindings[i] != null) { byte id = (byte)(arrIndex++); ymt.Unk_376833625.Unk_2996560424.SetByte(i, id); } ymt.Unk_376833625.Components[(Unk_884254308)i] = componentTextureBindings[i]; } } if (isAnyClothAdded || isAnyPropAdded) { using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(GenerateShopMeta((Sex)sexNr, collectionName)))) { var binFile = dataDir.CreateBinaryFile(); binFile.Name = prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName + ".meta"; binFile.Import(stream); } currComponentRpf.Flush(); var binRpfFile = cdimagesDir.CreateBinaryFile(); binRpfFile.Name = folderNames[sexNr].Replace("ped_", collectionName + "_") + ".rpf"; binRpfFile.Import(currComponentRpf.archive_.BaseStream); currComponentRpf.Dispose(); } if (isAnyPropAdded) { if (sexNr == 0) { hasMaleProps = true; } else if (sexNr == 1) { hasFemaleProps = true; } currPropRpf.Flush(); var binRpfFile = cdimagesDir.CreateBinaryFile(); binRpfFile.Name = folderNames[sexNr].Replace("ped_", collectionName + "_") + "_p.rpf"; binRpfFile.Import(currPropRpf.archive_.BaseStream); currPropRpf.Dispose(); } } using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(GenerateContentXML(collectionName, hasMale, hasFemale, hasMaleProps, hasFemaleProps)))) { var binFile = rpf.Root.CreateBinaryFile(); binFile.Name = "content.xml"; binFile.Import(stream); } using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(GenerateSetup2XML(collectionName)))) { var binFile = rpf.Root.CreateBinaryFile(); binFile.Name = "setup2.xml"; binFile.Import(stream); } rpf.Flush(); rpf.Dispose(); MessageBox.Show("Resource built!"); } }
static void HandleCreateArchiveOptions(string[] args) { CommandLine.Parse <CreateArchiveOptions>(args, (opts, gOpts) => { EnsurePath(); EnsureKeys(); if (opts.InputFolder == null) { Console.WriteLine("Please provide input folder with -i --input"); return; } if (opts.OutputFolder == null) { Console.WriteLine("Please provide output folder with -o --output"); return; } if (opts.Name == null) { Console.WriteLine("Please provide rpf name with -n --name"); return; } string rpfPath = opts.OutputFolder + "\\" + opts.Name + ".rpf"; using (RageArchiveWrapper7 rpf = RageArchiveWrapper7.Create(rpfPath)) { var queue = new List <Tuple <string, IArchiveDirectory, RageArchiveWrapper7> >() { new Tuple <string, IArchiveDirectory, RageArchiveWrapper7>(opts.InputFolder, rpf.Root, rpf) }; var subRpfs = new List <Tuple <DirectoryInfo, IArchiveDirectory, RageArchiveWrapper7> >(); rpf.archive_.Encryption = RageArchiveEncryption7.NG; var rpfs = new List <RageArchiveWrapper7>(); while (queue.Count > 0) { var folder = queue[0].Item1; var curr = queue[0].Item2; var currRpf = queue[0].Item3; if (rpfs.IndexOf(currRpf) == -1) { rpfs.Add(currRpf); } Console.WriteLine(folder); queue.RemoveAt(0); string newFolder = null; IArchiveDirectory newCurr = null; RageArchiveWrapper7 newCurrRpf = null; string[] folders = Directory.GetDirectories(folder); string[] files = Directory.GetFiles(folder); for (int i = 0; i < folders.Length; i++) { var folderInfo = new DirectoryInfo(folders[i]); newFolder = folders[i]; if (folders[i].EndsWith(".rpf")) { var tmpStream = new FileStream(Path.GetTempFileName(), FileMode.Open); var subRpf = RageArchiveWrapper7.Create(tmpStream, folderInfo.Name); subRpf.archive_.Encryption = RageArchiveEncryption7.NG; subRpfs.Add(new Tuple <DirectoryInfo, IArchiveDirectory, RageArchiveWrapper7>(folderInfo, curr, subRpf)); newCurr = subRpf.Root; newCurrRpf = subRpf; } else { var directory = curr.CreateDirectory(); directory.Name = folderInfo.Name; newCurr = directory; newCurrRpf = currRpf; } queue.Add(new Tuple <string, IArchiveDirectory, RageArchiveWrapper7>(newFolder, newCurr, newCurrRpf)); } if (folders.Length + files.Length == 0) { Console.WriteLine(" .\\.empty"); var binFile = curr.CreateBinaryFile(); binFile.Name = ".empty"; var ms = new MemoryStream(1); ms.WriteByte(0); ms.Flush(); binFile.Import(ms); } for (int i = 0; i < files.Length; i++) { string file = files[i]; var fileInfo = new FileInfo(file); bool isResource = false; for (int j = 0; j < ResourceFileTypes_GTA5_pc.AllTypes.Count; j++) { var type = ResourceFileTypes_GTA5_pc.AllTypes[j]; if (file.EndsWith(type.Extension)) { Console.WriteLine(" " + file); isResource = true; var resource = curr.CreateResourceFile(); resource.Name = fileInfo.Name; resource.Import(file); break; } } if (!isResource) { Console.WriteLine(" " + file); var binFile = curr.CreateBinaryFile(); binFile.Name = fileInfo.Name; binFile.Import(file); } } } rpfs.Reverse(); for (int i = 0; i < subRpfs.Count; i++) { var subRpf = subRpfs[i]; var file = subRpf.Item2.CreateBinaryFile(); file.Name = subRpf.Item1.Name; subRpf.Item3.Flush(); file.Import(subRpf.Item3.archive_.BaseStream); } for (int i = 0; i < rpfs.Count; i++) { rpfs[i].Flush(); if (i + 1 < rpfs.Count) { var stream = (FileStream)rpfs[i].archive_.BaseStream; string fileName = stream.Name; rpfs[i].Dispose(); File.Delete(fileName); } } } }); }