public void Load(byte[] data, RpfFileEntry entry) { Name = entry.Name; RpfFileEntry = entry; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry == null) { MemoryStream ms = new MemoryStream(data); if (RbfFile.IsRBF(ms)) { Rbf = new RbfFile(); Rbf.Load(ms); } else if (PsoFile.IsPSO(ms)) { Pso = new PsoFile(); Pso.Load(ms); //PsoTypes.EnsurePsoTypes(Pso); } else { } return; } ResourceDataReader rd = new ResourceDataReader(resentry, data); Meta = rd.ReadBlock <Meta>(); CMapTypes = MetaTypes.GetTypedData <CMapTypes>(Meta, MetaName.CMapTypes); List <Archetype> allarchs = new List <Archetype>(); var ptrs = MetaTypes.GetPointerArray(Meta, CMapTypes.archetypes); if (ptrs != null) { for (int i = 0; i < ptrs.Length; i++) { var ptr = ptrs[i]; var offset = ptr.Offset; var block = Meta.GetBlock(ptr.BlockID); if (block == null) { continue; } if ((offset < 0) || (block.Data == null) || (offset >= block.Data.Length)) { continue; } Archetype a = null; switch (block.StructureNameHash) { case MetaName.CBaseArchetypeDef: var basearch = PsoTypes.ConvertDataRaw <CBaseArchetypeDef>(block.Data, offset); a = new Archetype(); a.Init(this, ref basearch); a.Extensions = MetaTypes.GetExtensions(Meta, basearch.extensions); break; case MetaName.CTimeArchetypeDef: var timearch = PsoTypes.ConvertDataRaw <CTimeArchetypeDef>(block.Data, offset); var ta = new TimeArchetype(); ta.Init(this, ref timearch); ta.Extensions = MetaTypes.GetExtensions(Meta, timearch._BaseArchetypeDef.extensions); a = ta; break; case MetaName.CMloArchetypeDef: var mloarch = PsoTypes.ConvertDataRaw <CMloArchetypeDef>(block.Data, offset); var ma = new MloArchetype(); ma.Init(this, ref mloarch); ma.Extensions = MetaTypes.GetExtensions(Meta, mloarch._BaseArchetypeDef.extensions); ma.LoadChildren(Meta); a = ma; break; default: continue; } if (a != null) { allarchs.Add(a); } } } AllArchetypes = allarchs.ToArray(); Extensions = MetaTypes.GetExtensions(Meta, CMapTypes.extensions); if (Extensions != null) { } //AudioEmitters = MetaTypes.GetTypedDataArray<CExtensionDefAudioEmitter>(Meta, MetaName.CExtensionDefAudioEmitter); //if (AudioEmitters != null) //{ } //CEntityDefs = MetaTypes.GetTypedDataArray<CEntityDef>(Meta, MetaName.CEntityDef); CompositeEntityTypes = MetaTypes.ConvertDataArray <CCompositeEntityType>(Meta, MetaName.CCompositeEntityType, CMapTypes.compositeEntityTypes); if (CompositeEntityTypes != null) { } NameHash = CMapTypes.name; if (NameHash == 0) { int ind = entry.NameLower.LastIndexOf('.'); if (ind > 0) { NameHash = JenkHash.GenHash(entry.NameLower.Substring(0, ind)); } else { NameHash = JenkHash.GenHash(entry.NameLower); } } Strings = MetaTypes.GetStrings(Meta); if (Strings != null) { foreach (string str in Strings) { JenkIndex.Ensure(str); //just shove them in there } } //foreach (var block in Meta.DataBlocks) //{ // switch(block.StructureNameHash) // { // case MetaName.CMapTypes: // case MetaName.CTimeArchetypeDef: // case MetaName.CBaseArchetypeDef: // case MetaName.CMloArchetypeDef: // case MetaName.CMloTimeCycleModifier: // case MetaName.CMloRoomDef: // case MetaName.CMloPortalDef: // case MetaName.CMloEntitySet: // case MetaName.CEntityDef: // case MetaName.CExtensionDefParticleEffect: // case MetaName.CExtensionDefAudioCollisionSettings: // case MetaName.CExtensionDefSpawnPoint: // case MetaName.CExtensionDefSpawnPointOverride: // case MetaName.CExtensionDefExplosionEffect: // case MetaName.CExtensionDefAudioEmitter: // case MetaName.CExtensionDefLadder: // case MetaName.CExtensionDefBuoyancy: // case MetaName.CExtensionDefExpression: // case MetaName.CExtensionDefLightShaft: // case MetaName.CExtensionDefLightEffect: // case MetaName.CExtensionDefDoor: // case MetaName.CExtensionDefWindDisturbance: // case MetaName.CExtensionDefProcObject: // case MetaName.CLightAttrDef: // case MetaName.STRING: // case MetaName.POINTER: // case MetaName.UINT: // case MetaName.VECTOR4: // break; // default: // break; // } //} //MetaTypes.ParseMetaData(Meta); }
static void ExtractFilesInRPF(RpfFile rpf, string directoryOffset) { try { using (BinaryReader br = new BinaryReader(File.OpenRead(rpf.GetPhysicalFilePath()))) { foreach (RpfEntry entry in rpf.AllEntries) { if (!entry.NameLower.EndsWith(".rpf")) //don't try to extract rpf's, they will be done separately.. { if (entry is RpfBinaryFileEntry) { RpfBinaryFileEntry binentry = entry as RpfBinaryFileEntry; byte[] data = rpf.ExtractFileBinary(binentry, br); if (data == null) { if (binentry.FileSize == 0) { Console.WriteLine("Invalid binary file size!"); } else { Console.WriteLine("data is null!"); } } else if (data.Length == 0) { Console.WriteLine("{0} : Decompressed output was empty.", entry.Path); } else { Console.WriteLine("binary meme -> " + entry.NameLower); File.WriteAllBytes(directoryOffset + entry.NameLower, data); } } else if (entry is RpfResourceFileEntry) { RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; byte[] data = rpf.ExtractFileResource(resentry, br); data = ResourceBuilder.Compress(data); //not completely ideal to recompress it... data = ResourceBuilder.AddResourceHeader(resentry, data); if (data == null) { if (resentry.FileSize == 0) { Console.WriteLine("{0} : Resource FileSize is 0.", entry.Path); } else { Console.WriteLine("{0} : {1}", entry.Path); } } else if (data.Length == 0) { Console.WriteLine("{0} : Decompressed output was empty.", entry.Path); } else { Console.WriteLine("Potential meme -> " + entry.NameLower); foreach (KeyValuePair <string, string[]> extentionMap in extensions) { foreach (string extention in extentionMap.Value) { if (entry.NameLower.EndsWith(extention)) { Console.WriteLine("Resource meme -> " + entry.NameLower); if (extention.Equals(".ytd")) { RpfFileEntry rpfent = entry as RpfFileEntry; byte[] ytddata = rpfent.File.ExtractFile(rpfent); bool needsResized = ytddata.Length > 5242880; // 5MB YtdFile ytd = new YtdFile(); ytd.Load(ytddata, rpfent); Dictionary <uint, Texture> Dicts = new Dictionary <uint, Texture>(); bool somethingResized = false; foreach (KeyValuePair <uint, Texture> texture in ytd.TextureDict.Dict) { if (texture.Value.Width > 1440 || needsResized && texture.Value.Width > 550) // Only resize if it is greater than 1440p or 550p if vehicle is oversized { byte[] dds = DDSIO.GetDDSFile(texture.Value); string fileName = $"{texture.Value.Name}.dds"; fileName = String.Concat(fileName.Where(c => !Char.IsWhiteSpace(c))); File.WriteAllBytes("./NConvert/" + fileName, dds); Process p = new Process(); p.StartInfo.FileName = @"./NConvert/nconvert.exe"; p.StartInfo.Arguments = @"-out dds -resize 50% 50% -overwrite ./NConvert/" + fileName; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); //Wait for the process to end. p.WaitForExit(); // Move file back File.Move("./NConvert/" + fileName, directoryOffset + fileName); byte[] resizedData = File.ReadAllBytes(directoryOffset + fileName); Texture resizedTex = DDSIO.GetTexture(resizedData); resizedTex.Name = texture.Value.Name; Console.WriteLine(resizedData.Length.ToString()); Dicts.Add(texture.Key, resizedTex); // Yeet the file, we are done with it File.Delete(directoryOffset + fileName); somethingResized = true; } else { Dicts.Add(texture.Key, texture.Value); } } // No point rebuilding the ytd when nothing was resized if (!somethingResized) { break; } TextureDictionary dic = new TextureDictionary(); dic.Textures = new ResourcePointerList64 <Texture>(); dic.TextureNameHashes = new ResourceSimpleList64_uint(); dic.Textures.data_items = Dicts.Values.ToArray(); dic.TextureNameHashes.data_items = Dicts.Keys.ToArray(); dic.BuildDict(); ytd.TextureDict = dic; byte[] resizedYtdData = ytd.Save(); File.WriteAllBytes(directoryOffset + entry.NameLower, resizedYtdData); Console.WriteLine("Done some ytd resize memes -> " + entry.NameLower); break; } File.WriteAllBytes(directoryOffset + entry.NameLower, data); break; } } } if (entry.NameLower.EndsWith(".ytd")) { latestModelName = entry.NameLower.Remove(entry.NameLower.Length - 4); } } } } else { // Write file first RpfBinaryFileEntry binentry = entry as RpfBinaryFileEntry; byte[] data = rpf.ExtractFileBinary(binentry, br); File.WriteAllBytes(directoryOffset + entry.NameLower, data); RpfFile subRPF = new RpfFile(directoryOffset + entry.NameLower, directoryOffset + entry.NameLower); if (subRPF.ScanStructure(null, null)) { //recursive memes ExtractFilesInRPF(subRPF, directoryOffset); } //yeet File.Delete(directoryOffset + entry.NameLower); } } } } catch (Exception e) { Console.WriteLine("Exception memes!"); Console.WriteLine(e.Message); } }
public void Load(byte[] data, RpfFileEntry entry) { Name = entry.Name; RpfFileEntry = entry; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry == null) { NonMetaLoad(data); return; } ResourceDataReader rd = new ResourceDataReader(resentry, data); Meta = rd.ReadBlock <Meta>(); CMapData = MetaTypes.GetTypedData <CMapData>(Meta, MetaName.CMapData); Strings = MetaTypes.GetStrings(Meta); if (Strings != null) { foreach (string str in Strings) { JenkIndex.Ensure(str); //just shove them in there } } physicsDictionaries = MetaTypes.GetHashArray(Meta, CMapData.physicsDictionaries); EnsureEntities(Meta); //load all the entity data and create the YmapEntityDefs EnsureInstances(Meta); EnsureLodLights(Meta); EnsureDistantLODLights(Meta); EnsureTimeCycleModifiers(Meta); EnsureCarGens(Meta); EnsureBoxOccluders(Meta); EnsureOccludeModels(Meta); EnsureContainerLods(Meta); #region data block test and old code //foreach (var block in Meta.DataBlocks) //{ // switch (block.StructureNameHash) // { // case MetaName.STRING: // case MetaName.POINTER: // case MetaName.HASH: // case MetaName.UINT: // case MetaName.VECTOR3: //distant lod lights uses this // case MetaName.CMapData: // case MetaName.CEntityDef: // case MetaName.CTimeCycleModifier: //these sections are handled already // case MetaName.CCarGen: // case MetaName.CLightAttrDef: // case MetaName.CMloInstanceDef: // case MetaName.CExtensionDefDoor: // case MetaName.CExtensionDefLightEffect: // case MetaName.CExtensionDefSpawnPointOverride: // case MetaName.rage__fwGrassInstanceListDef: //grass instance buffer // case MetaName.rage__fwGrassInstanceListDef__InstanceData: //grass instance buffer data // break; // case MetaName.PhVerletClothCustomBounds: //these sections still todo.. // case MetaName.SectionUNKNOWN1: // case MetaName.SectionUNKNOWN5://occlusion vertex data container // case MetaName.SectionUNKNOWN7://occlusion related? // break; // case (MetaName)17: //vertex data - occlusion related - SectionUNKNOWN5 // break; // case (MetaName)33: //what is this? maybe lodlights related // break; // default: // break; // } //} //MetaTypes.ParseMetaData(Meta); //string shortname = resentry.Name.Substring(0, resentry.Name.LastIndexOf('.')); //uint namehash = JenkHash.GenHash(shortname); //CLightAttrDefs = MetaTypes.GetTypedDataArray<CLightAttrDef>(Meta, MetaName.CLightAttrDef); //if (CLightAttrDefs != null) //{ } //var unk5s = MetaTypes.GetTypedDataArray<SectionUNKNOWN5>(Meta, MetaName.SectionUNKNOWN5); //if (unk5s != null) //used in occlusion ymaps //{ // foreach (var unk5 in unk5s) // { // if ((unk5.verts.Ptr > 0) && (unk5.verts.Ptr <= (ulong)Meta.DataBlocks.Length)) // { // var indicesoffset = unk5.Unk_853977995; // var datablock = Meta.DataBlocks[((int)unk5.verts.Ptr) - 1]; // if (datablock != null) // { }//vertex data... occlusion mesh? // } // } //} //var unk7s = MetaTypes.GetTypedDataArray<SectionUNKNOWN7>(Meta, MetaName.SectionUNKNOWN7); //if (unk7s != null) //{ } //used in occlusion ymaps //var unk10s = MetaTypes.GetTypedDataArray<SectionUNKNOWN10>(Meta, MetaName.SectionUNKNOWN10); //if (unk10s != null) //{ } //entity pointer array.. //CDoors = MetaTypes.GetTypedDataArray<CExtensionDefDoor>(Meta, MetaName.CExtensionDefDoor); //if (CDoors != null) //{ } //needs work - doors can be different types? not enough bytes for one //CExtLightEffects = MetaTypes.GetTypedDataArray<CExtensionDefLightEffect>(Meta, MetaName.CExtensionDefLightEffect); //if (CExtLightEffects != null) //{ } //CSpawnOverrides = MetaTypes.GetTypedDataArray<CExtensionDefSpawnPointOverride>(Meta, MetaName.CExtensionDefSpawnPointOverride); //if (CSpawnOverrides != null) //{ } #endregion }
public void Load(byte[] data, RpfFileEntry entry) { RpfFileEntry = entry; Name = entry.Name; FilePath = Name; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry != null) { ResourceDataReader rd = new ResourceDataReader(resentry, data); Meta = rd.ReadBlock <Meta>(); var rootblock = Meta.GetRootBlock(); if (rootblock != null) { if (rootblock.StructureNameHash == MetaName.CScenarioPointRegion) { LoadScenarioPointRegion(Meta, rootblock); } } Loaded = true; return; } MemoryStream ms = new MemoryStream(data); if (RbfFile.IsRBF(ms)) { Rbf = new RbfFile(); var rbfstruct = Rbf.Load(ms); if (rbfstruct.Name == "CMapParentTxds") { LoadMapParentTxds(rbfstruct); } Loaded = true; return; } if (PsoFile.IsPSO(ms)) { Pso = new PsoFile(); Pso.Load(ms); //PsoTypes.EnsurePsoTypes(Pso); var root = PsoTypes.GetRootEntry(Pso); if (root != null) { if (root.NameHash == MetaName.CScenarioPointManifest) { LoadScenarioPointManifest(Pso); } } Loaded = true; return; } else { } }
private void ExportButton_Click(object sender, EventArgs e) { if (InProgress) { return; } if (ScannedFiles.Count == 0) { MessageBox.Show("Please scan the GTAV folder first."); return; } TreeNode node = MainTreeView.SelectedNode; if (node == null) { MessageBox.Show("Please select a file to export."); return; } RpfFileEntry rfe = node.Tag as RpfFileEntry; if (rfe == null) { MessageBox.Show("Please select a file to export."); return; } SaveFileDialog.FileName = rfe.Name; if (SaveFileDialog.ShowDialog() == DialogResult.OK) { string fpath = SaveFileDialog.FileName; byte[] data = rfe.File.ExtractFile(rfe); if (ExportCompressCheckBox.Checked) { data = ResourceBuilder.Compress(data); } RpfResourceFileEntry rrfe = rfe as RpfResourceFileEntry; if (rrfe != null) //add resource header if this is a resource file. { data = ResourceBuilder.AddResourceHeader(rrfe, data); } if (data == null) { MessageBox.Show("Error extracting file! " + rfe.File.LastError); return; } try { File.WriteAllBytes(fpath, data); } catch (Exception ex) { MessageBox.Show("Error saving file! " + ex.ToString()); } } }
public void Load(byte[] data, RpfFileEntry entry) { Name = entry.Name; RpfFileEntry = entry; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry == null) { throw new Exception("File entry wasn't a resource! (is it binary data?)"); } ResourceDataReader rd = new ResourceDataReader(resentry, data); Nav = rd.ReadBlock <NavMesh>(); if (Nav != null) { Vector3 posoffset = Nav.SectorTree?.AABBMin.XYZ() ?? Vector3.Zero; Vector3 aabbsize = Nav.AABBSize; if (Nav.Vertices != null) { var verts = Nav.Vertices.GetFullList(); Vertices = new List <Vector3>(verts.Count); for (int i = 0; i < verts.Count; i++) { var ov = verts[i].ToVector3(); Vertices.Add(posoffset + ov * aabbsize); } } if (Nav.Indices != null) { Indices = Nav.Indices.GetFullList(); } if (Nav.Edges != null) { var edges = Nav.Edges.GetFullList(); Edges = new List <YnvEdge>(edges.Count); for (int i = 0; i < edges.Count; i++) { YnvEdge edge = new YnvEdge(); edge.Init(this, edges[i]); Edges.Add(edge); } } if (Nav.Polys != null) { var polys = Nav.Polys.GetFullList(); Polys = new List <YnvPoly>(polys.Count); for (int i = 0; i < polys.Count; i++) { YnvPoly poly = new YnvPoly(); poly.Init(this, polys[i]); poly.Index = i; Polys.Add(poly); } } if (Nav.Portals != null) { var portals = Nav.Portals; Portals = new List <YnvPortal>(portals.Length); for (int i = 0; i < portals.Length; i++) { YnvPortal portal = new YnvPortal(); portal.Init(this, portals[i]); portal.Index = i; portal.PositionFrom = posoffset + portal._RawData.PositionFrom.ToVector3() * aabbsize; portal.PositionTo = posoffset + portal._RawData.PositionTo.ToVector3() * aabbsize; Portals.Add(portal); } } ////### add points to the list and calculate positions... var treestack = new Stack <NavMeshSector>(); var pointi = 0; if (Nav.SectorTree != null) { treestack.Push(Nav.SectorTree); } while (treestack.Count > 0) { var sector = treestack.Pop(); if (sector.Data != null) { var points = sector.Data.Points; if (points != null) { if (Points == null) { Points = new List <YnvPoint>(); } for (int i = 0; i < points.Length; i++) { YnvPoint point = new YnvPoint(); point.Init(this, points[i]); point.Index = pointi; pointi++; point.Position = posoffset + point._RawData.Position * aabbsize; Points.Add(point); } } } if (sector.SubTree1 != null) { treestack.Push(sector.SubTree1); } if (sector.SubTree2 != null) { treestack.Push(sector.SubTree2); } if (sector.SubTree3 != null) { treestack.Push(sector.SubTree3); } if (sector.SubTree4 != null) { treestack.Push(sector.SubTree4); } } } UpdateAllNodePositions(); UpdateTriangleVertices(); BuildBVH(); Loaded = true; LoadQueued = true; }
public void Load(byte[] data, RpfFileEntry entry) { Name = entry.Name; RpfFileEntry = entry; //Hash = entry.ShortNameHash; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry == null) { throw new Exception("File entry wasn't a resource! (is it binary data?)"); } ResourceDataReader rd = new ResourceDataReader(resentry, data); ClipDictionary = rd.ReadBlock <ClipDictionary>(); ClipMap = new Dictionary <MetaHash, ClipMapEntry>(); AnimMap = new Dictionary <MetaHash, AnimationMapEntry>(); if (ClipDictionary != null) { if ((ClipDictionary.Clips != null) && (ClipDictionary.Clips.data_items != null)) { foreach (var cme in ClipDictionary.Clips.data_items) { if (cme != null) { ClipMap[cme.Hash] = cme; var nxt = cme.Next; while (nxt != null) { ClipMap[nxt.Hash] = nxt; nxt = nxt.Next; } } } } if ((ClipDictionary.Animations != null) && (ClipDictionary.Animations.Animations != null) && (ClipDictionary.Animations.Animations.data_items != null)) { foreach (var ame in ClipDictionary.Animations.Animations.data_items) { if (ame != null) { AnimMap[ame.Hash] = ame; var nxt = ame.NextEntry; while (nxt != null) { AnimMap[nxt.Hash] = nxt; nxt = nxt.NextEntry; } } } } } foreach (var cme in ClipMap.Values) { var clip = cme.Clip; if (clip == null) { continue; } clip.Ycd = this; if (string.IsNullOrEmpty(clip.Name)) { continue; } string name = clip.Name.Replace('\\', '/'); var slidx = name.LastIndexOf('/'); if ((slidx >= 0) && (slidx < name.Length - 1)) { name = name.Substring(slidx + 1); } var didx = name.LastIndexOf('.'); if ((didx > 0) && (didx < name.Length)) { name = name.Substring(0, didx); } clip.ShortName = name; name = name.ToLowerInvariant(); JenkIndex.Ensure(name); //if (name.EndsWith("_uv_0")) //hash for these entries match string with this removed, +1 //{ //} //if (name.EndsWith("_uv_1")) //same as above, but +2 //{ //} } foreach (var ame in AnimMap.Values) { var anim = ame.Animation; if (anim == null) { continue; } anim.Ycd = this; } ClipMapEntries = ClipMap.Values.ToArray(); AnimMapEntries = AnimMap.Values.ToArray(); }
public static void AssignPositionsForMeta(IList <IResourceBlock> blocks, uint basePosition, out RpfResourcePageFlags pageFlags) { // find largest structure long largestBlockSize = 0; foreach (var block in blocks) { if (largestBlockSize < block.BlockLength) { largestBlockSize = block.BlockLength; } } // find minimum page size long currentPageSize = 0x2000; while (currentPageSize < largestBlockSize) { currentPageSize *= 2; } long currentPageCount; long currentPosition; while (true) { currentPageCount = 0; currentPosition = 0; // reset all positions foreach (var block in blocks) { block.FilePosition = -1; } foreach (var block in blocks) { if (block.FilePosition != -1) { throw new Exception("Block was already assigned a position!"); } // check if new page is necessary... // if yes, add a new page and align to it long maxSpace = currentPageCount * currentPageSize - currentPosition; if (maxSpace < (block.BlockLength + SKIP_SIZE)) { currentPageCount++; currentPosition = currentPageSize * (currentPageCount - 1); } // set position block.FilePosition = basePosition + currentPosition; currentPosition += block.BlockLength; // + SKIP_SIZE; //is padding everywhere really necessary?? // align... if ((currentPosition % ALIGN_SIZE) != 0) { currentPosition += (ALIGN_SIZE - (currentPosition % ALIGN_SIZE)); } } // break if everything fits... if (currentPageCount < 128) { break; } currentPageSize *= 2; } pageFlags = new RpfResourcePageFlags(RpfResourceFileEntry.GetFlagsFromBlocks((uint)currentPageCount, (uint)currentPageSize, 0)); }
public void Load(byte[] data, RpfFileEntry entry) { Name = entry.Name; RpfFileEntry = entry; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry == null) { throw new Exception("File entry wasn't a resource! (is it binary data?)"); } ResourceDataReader rd = new ResourceDataReader(resentry, data); NodeDictionary = rd.ReadBlock <NodeDictionary>(); if (NodeDictionary != null) { if (NodeDictionary.Nodes != null) { var nodes = NodeDictionary.Nodes; Nodes = new YndNode[nodes.Length]; for (int i = 0; i < nodes.Length; i++) { var n = new YndNode(); n.Init(this, nodes[i]); Nodes[i] = n; if (n.NodeID != i) { } //never hit here - nodeid's have to match the index! } } if ((NodeDictionary.JunctionRefs != null) && (NodeDictionary.Junctions != null)) { var juncrefs = NodeDictionary.JunctionRefs; var juncs = NodeDictionary.Junctions; Junctions = new YndJunction[juncrefs.Length]; for (int i = 0; i < juncrefs.Length; i++) { var juncref = NodeDictionary.JunctionRefs[i]; if (juncref.JunctionID >= juncs.Length) { continue; } var j = new YndJunction(); j.Init(this, juncs[juncref.JunctionID], juncref); j.Heightmap = new YndJunctionHeightmap(NodeDictionary.JunctionHeightmapBytes, j); Junctions[i] = j; } } } UpdateAllNodePositions(); //links will be populated by the space... maybe move that code here? string areaidstr = Name.ToLower().Replace("nodes", "").Replace(".ynd", ""); int areaid = 0; int.TryParse(areaidstr, out areaid); AreaID = areaid; UpdateBoundingBox(); BuildBVH(); Loaded = true; LoadQueued = true; }
private void ExtractButton_Click(object sender, EventArgs e) { if (InProgress) { return; } if (!KeysLoaded) { MessageBox.Show("Please scan a GTA 5 exe dump for keys first, or include key files in this app's folder!"); return; } if (!Directory.Exists(FolderTextBox.Text)) { MessageBox.Show("Folder doesn't exist: " + FolderTextBox.Text); return; } if (!Directory.Exists(OutputFolderTextBox.Text)) { MessageBox.Show("Folder doesn't exist: " + OutputFolderTextBox.Text); return; } if (string.IsNullOrEmpty(FileMatchTextBox.Text) || (FileMatchTextBox.Text.Length < 3)) { MessageBox.Show("Please enter at least 3 characters to match."); return; } InProgress = true; AbortOperation = false; string searchpath = FolderTextBox.Text; string outputpath = OutputFolderTextBox.Text; string replpath = searchpath + "\\"; string matchstr = FileMatchTextBox.Text; bool endswith = MatchEndsWithRadio.Checked; bool compress = CompressCheckBox.Checked; Task.Run(() => { UpdateExtractStatus("Keys loaded."); RpfManager rpfman = new RpfManager(); rpfman.Init(searchpath, UpdateExtractStatus, UpdateExtractStatus); UpdateExtractStatus("Beginning file extraction..."); StringBuilder errsb = new StringBuilder(); foreach (RpfFile rpf in rpfman.AllRpfs) { foreach (RpfEntry entry in rpf.AllEntries) { if (AbortOperation) { UpdateExtractStatus("Operation aborted"); InProgress = false; return; } try { bool extract = false; if (endswith) { extract = entry.NameLower.EndsWith(matchstr); } else { extract = entry.NameLower.Contains(matchstr); } var fentry = entry as RpfFileEntry; if (fentry == null) { extract = false; } if (extract) { UpdateExtractStatus(entry.Path); byte[] data = entry.File.ExtractFile(fentry); if (compress) { data = ResourceBuilder.Compress(data); } RpfResourceFileEntry rrfe = fentry as RpfResourceFileEntry; if (rrfe != null) //add resource header if this is a resource file. { data = ResourceBuilder.AddResourceHeader(rrfe, data); } if (data != null) { var finf = new FileInfo(entry.Name); string bpath = outputpath + "\\" + entry.Name.Substring(0, entry.Name.Length - finf.Extension.Length); string fpath = bpath + finf.Extension; int c = 1; while (File.Exists(fpath)) { fpath = bpath + "_" + c.ToString() + finf.Extension; c++; } File.WriteAllBytes(fpath, data); } else { throw new Exception("Couldn't extract data."); } } } catch (Exception ex) { string err = entry.Name + ": " + ex.Message; UpdateExtractStatus(err); errsb.AppendLine(err); } } } File.WriteAllText(outputpath + "\\_errors.txt", errsb.ToString()); UpdateExtractStatus("Complete."); InProgress = false; }); }
public void Load(byte[] data, RpfFileEntry entry) { Name = entry.Name; RpfFileEntry = entry; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry == null) { throw new Exception("File entry wasn't a resource! (is it binary data?)"); } ResourceDataReader rd = new ResourceDataReader(resentry, data); DrawableDict = rd.ReadBlock <DrawableDictionary>(); //MemoryUsage = 0; //uses decompressed filesize now... //if (DrawableDict != null) //{ // MemoryUsage += DrawableDict.MemoryUsage; //} if ((DrawableDict != null) && (DrawableDict.Drawables != null) && (DrawableDict.Drawables.data_items != null) && (DrawableDict.Hashes != null)) { Dict = new Dictionary <uint, Drawable>(); var drawables = DrawableDict.Drawables.data_items; var hashes = DrawableDict.Hashes; for (int i = 0; (i < drawables.Length) && (i < hashes.Length); i++) { var drawable = drawables[i]; var hash = hashes[i]; Dict[hash] = drawable; drawable.Owner = this; } for (int i = 0; (i < drawables.Length) && (i < hashes.Length); i++) { var drawable = drawables[i]; var hash = hashes[i]; if ((drawable.Name == null) || (drawable.Name.EndsWith("#dd"))) { string hstr = JenkIndex.TryGetString(hash); if (!string.IsNullOrEmpty(hstr)) { drawable.Name = hstr; } else { } } } Drawables = Dict.Values.ToArray(); } Loaded = true; }
public void Load(byte[] data, RpfFileEntry entry) { Name = entry.Name; RpfFileEntry = entry; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry == null) { throw new Exception("File entry wasn't a resource! (is it binary data?)"); } ResourceDataReader rd = new ResourceDataReader(resentry, data); //MemoryUsage = 0; try { PtfxList = rd.ReadBlock <ParticleEffectsList>(); //Drawable.Owner = this; //MemoryUsage += Drawable.MemoryUsage; //uses decompressed filesize now... } catch (Exception ex) { ErrorMessage = ex.ToString(); } var dDict = PtfxList?.DrawableDictionary; if ((dDict != null) && (dDict.Drawables != null) && (dDict.Drawables.data_items != null) && (dDict.Hashes != null)) { DrawableDict = new Dictionary <uint, Drawable>(); var drawables = dDict.Drawables.data_items; var hashes = dDict.Hashes; for (int i = 0; (i < drawables.Length) && (i < hashes.Length); i++) { var drawable = drawables[i]; var hash = hashes[i]; DrawableDict[hash] = drawable; drawable.Owner = this; } for (int i = 0; (i < drawables.Length) && (i < hashes.Length); i++) { var drawable = drawables[i]; var hash = hashes[i]; if ((drawable.Name == null) || (drawable.Name.EndsWith("#dd"))) { string hstr = JenkIndex.TryGetString(hash); if (!string.IsNullOrEmpty(hstr)) { drawable.Name = hstr; } else { drawable.Name = "0x" + hash.ToString("X").PadLeft(8, '0'); } } } } Loaded = true; }
public void Load(byte[] data, RpfFileEntry entry) { Name = entry.Name; RpfFileEntry = entry; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry == null) { throw new Exception("File entry wasn't a resource! (is it binary data?)"); } ResourceDataReader rd = new ResourceDataReader(resentry, data); Nav = rd.ReadBlock <NavMesh>(); if ((Nav != null) && (Nav.SectorTree != null)) { if (Nav.Vertices != null) { Vector3 posoffset = Nav.SectorTree.AABBMin.XYZ(); Vector3 aabbsize = Nav.AABBSize; var verts = Nav.Vertices.GetFullList(); Vertices = new List <Vector3>(verts.Count); for (int i = 0; i < verts.Count; i++) { var ov = verts[i].ToVector3(); Vertices.Add(posoffset + ov * aabbsize); } } if (Nav.Indices != null) { Indices = Nav.Indices.GetFullList(); } if (Nav.Polys != null) { var polys = Nav.Polys.GetFullList(); Polys = new List <YnvPoly>(polys.Count); for (int i = 0; i < polys.Count; i++) { YnvPoly poly = new YnvPoly(); poly.Init(this, polys[i]); poly.Index = i; Polys.Add(poly); //calc poly center. if ((Indices == null) || (Vertices == null)) { continue; } var vc = Vertices.Count; var ic = poly._RawData.IndexCount; var startid = poly._RawData.IndexID; var endid = startid + ic; if (startid >= Indices.Count) { continue; } if (endid > Indices.Count) { continue; } Vector3 pcenter = Vector3.Zero; float pcount = 0.0f; for (int id = startid; id < endid; id++) { var ind = Indices[id]; if (ind >= vc) { continue; } pcenter += Vertices[ind]; pcount += 1.0f; } poly.Position = pcenter * (1.0f / pcount); } } } UpdateAllNodePositions(); UpdateTriangleVertices(); Loaded = true; LoadQueued = true; }
public static byte[] Build(ResourceFileBase fileBase, int version, bool compress = true) { fileBase.FilePagesInfo = new ResourcePagesInfo(); IList <IResourceBlock> systemBlocks; IList <IResourceBlock> graphicBlocks; GetBlocks(fileBase, out systemBlocks, out graphicBlocks); int systemPageSize = BASE_SIZE;// *4; int systemPageCount; AssignPositions(systemBlocks, 0x50000000, ref systemPageSize, out systemPageCount); int graphicsPageSize = BASE_SIZE; int graphicsPageCount; AssignPositions(graphicBlocks, 0x60000000, ref graphicsPageSize, out graphicsPageCount); //fileBase.FilePagesInfo.SystemPagesCount = 0; //if (systemPageCount > 0) // fileBase.FilePagesInfo.SystemPagesCount = 1; // (byte)systemPageCount; //1 fileBase.FilePagesInfo.SystemPagesCount = (byte)systemPageCount; fileBase.FilePagesInfo.GraphicsPagesCount = (byte)graphicsPageCount; var systemStream = new MemoryStream(); var graphicsStream = new MemoryStream(); var resourceWriter = new ResourceDataWriter(systemStream, graphicsStream); resourceWriter.Position = 0x50000000; foreach (var block in systemBlocks) { resourceWriter.Position = block.FilePosition; var pos_before = resourceWriter.Position; block.Write(resourceWriter); var pos_after = resourceWriter.Position; if ((pos_after - pos_before) != block.BlockLength) { throw new Exception("error in system length"); } } resourceWriter.Position = 0x60000000; foreach (var block in graphicBlocks) { resourceWriter.Position = block.FilePosition; var pos_before = resourceWriter.Position; block.Write(resourceWriter); var pos_after = resourceWriter.Position; if ((pos_after - pos_before) != block.BlockLength) { throw new Exception("error in graphics length"); } } var sysDataSize = systemPageCount * systemPageSize; var sysData = new byte[sysDataSize]; systemStream.Flush(); systemStream.Position = 0; systemStream.Read(sysData, 0, (int)systemStream.Length); var gfxDataSize = graphicsPageCount * graphicsPageSize; var gfxData = new byte[gfxDataSize]; graphicsStream.Flush(); graphicsStream.Position = 0; graphicsStream.Read(gfxData, 0, (int)graphicsStream.Length); uint uv = (uint)version; uint sv = (uv >> 4) & 0xF; uint gv = (uv >> 0) & 0xF; //uint sf = RpfResourceFileEntry.GetFlagsFromSize(sysDataSize, sv); //uint gf = RpfResourceFileEntry.GetFlagsFromSize(gfxDataSize, gv); //TODO: might be broken... uint sf = RpfResourceFileEntry.GetFlagsFromBlocks((uint)systemPageCount, (uint)systemPageSize, sv); uint gf = RpfResourceFileEntry.GetFlagsFromBlocks((uint)graphicsPageCount, (uint)graphicsPageSize, gv); var tdatasize = sysDataSize + gfxDataSize; var tdata = new byte[tdatasize]; Buffer.BlockCopy(sysData, 0, tdata, 0, sysDataSize); Buffer.BlockCopy(gfxData, 0, tdata, sysDataSize, gfxDataSize); var cdata = compress ? Compress(tdata) : tdata; var dataSize = 16 + cdata.Length;// sysDataSize + gfxDataSize; var data = new byte[dataSize]; byte[] h1 = BitConverter.GetBytes((uint)0x37435352); byte[] h2 = BitConverter.GetBytes((int)version); byte[] h3 = BitConverter.GetBytes(sf); byte[] h4 = BitConverter.GetBytes(gf); Buffer.BlockCopy(h1, 0, data, 0, 4); Buffer.BlockCopy(h2, 0, data, 4, 4); Buffer.BlockCopy(h3, 0, data, 8, 4); Buffer.BlockCopy(h4, 0, data, 12, 4); Buffer.BlockCopy(cdata, 0, data, 16, cdata.Length); //Buffer.BlockCopy(sysData, 0, data, 16, sysDataSize); //Buffer.BlockCopy(gfxData, 0, data, 16 + sysDataSize, gfxDataSize); return(data); }
public void Load(byte[] data, RpfFileEntry entry) { FileEntry = entry; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry == null) { MemoryStream ms = new MemoryStream(data); if (RbfFile.IsRBF(ms)) { Rbf = new RbfFile(); Rbf.Load(ms); } else if (PsoFile.IsPSO(ms)) { Pso = new PsoFile(); Pso.Load(ms); //PsoTypes.EnsurePsoTypes(Pso); } else { } return; } ResourceDataReader rd = new ResourceDataReader(resentry, data); Meta = rd.ReadBlock <Meta>(); CMapTypes = MetaTypes.GetTypedData <CMapTypes>(Meta, MetaName.CMapTypes); List <Archetype> allarchs = new List <Archetype>(); var ptrs = MetaTypes.GetPointerArray(Meta, CMapTypes.archetypes); if (ptrs != null) { for (int i = 0; i < ptrs.Length; i++) { var ptr = ptrs[i]; int blocki = ptr.BlockID - 1; int offset = ptr.ItemOffset * 16;//block data size... if (blocki >= Meta.DataBlocks.Count) { continue; } var block = Meta.DataBlocks[blocki]; if ((offset < 0) || (block.Data == null) || (offset >= block.Data.Length)) { continue; } var ba = new Archetype(); switch (block.StructureNameHash) { case MetaName.CBaseArchetypeDef: var basearch = PsoTypes.ConvertDataRaw <CBaseArchetypeDef>(block.Data, offset); ba.Init(this, basearch); ba.Extensions = MetaTypes.GetExtensions(Meta, basearch.extensions); break; case MetaName.CTimeArchetypeDef: var timearch = PsoTypes.ConvertDataRaw <CTimeArchetypeDef>(block.Data, offset); ba.Init(this, timearch); ba.Extensions = MetaTypes.GetExtensions(Meta, timearch.CBaseArchetypeDef.extensions); break; case MetaName.CMloArchetypeDef: var mloarch = PsoTypes.ConvertDataRaw <CMloArchetypeDef>(block.Data, offset); ba.Init(this, mloarch); ba.Extensions = MetaTypes.GetExtensions(Meta, mloarch.CBaseArchetypeDef.extensions); MloArchetypeData mlod = new MloArchetypeData(); mlod.entities = MetaTypes.ConvertDataArray <CEntityDef>(Meta, MetaName.CEntityDef, mloarch.entities); mlod.rooms = MetaTypes.ConvertDataArray <CMloRoomDef>(Meta, MetaName.CMloRoomDef, mloarch.rooms); mlod.portals = MetaTypes.ConvertDataArray <CMloPortalDef>(Meta, MetaName.CMloPortalDef, mloarch.portals); mlod.entitySets = MetaTypes.ConvertDataArray <CMloEntitySet>(Meta, MetaName.CMloEntitySet, mloarch.entitySets); mlod.timeCycleModifiers = MetaTypes.ConvertDataArray <CMloTimeCycleModifier>(Meta, MetaName.CMloTimeCycleModifier, mloarch.timeCycleModifiers); ba.MloData = mlod; //if (mlod.entities != null) //{ // for (int e = 0; e < mlod.entities.Length; e++) // { // EnsureEntityExtensions(Meta, ref mlod.entities[e]); // } //} break; default: continue; } allarchs.Add(ba); } } AllArchetypes = allarchs.ToArray(); Extensions = MetaTypes.GetExtensions(Meta, CMapTypes.extensions); if (Extensions != null) { } AudioEmitters = MetaTypes.GetTypedDataArray <CExtensionDefAudioEmitter>(Meta, MetaName.CExtensionDefAudioEmitter); if (AudioEmitters != null) { } //CEntityDefs = MetaTypes.GetTypedDataArray<CEntityDef>(Meta, MetaName.CEntityDef); CompositeEntityTypes = MetaTypes.ConvertDataArray <CCompositeEntityType>(Meta, MetaName.CCompositeEntityType, CMapTypes.compositeEntityTypes); if (CompositeEntityTypes != null) { } NameHash = CMapTypes.name; if (NameHash == 0) { int ind = entry.NameLower.LastIndexOf('.'); if (ind > 0) { NameHash = JenkHash.GenHash(entry.NameLower.Substring(0, ind)); } else { NameHash = JenkHash.GenHash(entry.NameLower); } } Strings = MetaTypes.GetStrings(Meta); if (Strings != null) { foreach (string str in Strings) { JenkIndex.Ensure(str); //just shove them in there } } foreach (var block in Meta.DataBlocks) { switch (block.StructureNameHash) { case MetaName.CMapTypes: case MetaName.CTimeArchetypeDef: case MetaName.CBaseArchetypeDef: case MetaName.CMloArchetypeDef: case MetaName.CMloTimeCycleModifier: case MetaName.CMloRoomDef: case MetaName.CMloPortalDef: case MetaName.CMloEntitySet: case MetaName.CEntityDef: case MetaName.CExtensionDefParticleEffect: case MetaName.CExtensionDefAudioCollisionSettings: case MetaName.CExtensionDefSpawnPoint: case MetaName.CExtensionDefSpawnPointOverride: case MetaName.CExtensionDefExplosionEffect: case MetaName.CExtensionDefAudioEmitter: case MetaName.CExtensionDefLadder: case MetaName.CExtensionDefBuoyancy: case MetaName.CExtensionDefExpression: case MetaName.CExtensionDefLightShaft: case MetaName.CExtensionDefLightEffect: case MetaName.CExtensionDefDoor: case MetaName.CExtensionDefWindDisturbance: case MetaName.CExtensionDefProcObject: case MetaName.CLightAttrDef: case MetaName.STRING: //case MetaName.SectionUNKNOWN2: //case MetaName.SectionUNKNOWN3: //case MetaName.SectionUNKNOWN8: case MetaName.POINTER: case MetaName.UINT: case MetaName.VECTOR4: break; default: break; } } //MetaTypes.ParseMetaData(Meta); //RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; //if (resentry == null) //{ // throw new Exception("File entry wasn't a resource! (is it binary data?)"); //} //ResourceDataReader rd = new ResourceDataReader(resentry, data); //Meta = rd.ReadBlock<Meta>(); //MetaTypes.EnsureMetaTypes(Meta); //MetaTypes.ParseMetaData(Meta); }