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!"); } }
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(); } } } } }); }