/// <summary> /// Update the data offset for a given file, adding the file if needed. /// Returns the previous Raw Data Offset (with dat Number Embedded), or 0 if the file did not exist. /// /// Setting a value of 0 for the offset will remove the file pointer. /// </summary> public uint SetDataOffset(string filePath, uint newRawOffsetWithDatNumEmbed) { var fileName = Path.GetFileName(filePath); var folderName = filePath.Substring(0, filePath.LastIndexOf('/')); var fileHash = (uint)HashGenerator.GetHash(fileName); var folderHash = (uint)HashGenerator.GetHash(folderName); var fullHash = (uint)HashGenerator.GetHash(filePath); if (!Index1Entries.ContainsKey(folderHash)) { Index1Entries.Add(folderHash, new Dictionary <uint, FileIndexEntry>()); } uint originalOffset = 0; if (!Index1Entries[folderHash].ContainsKey(fileHash)) { if (newRawOffsetWithDatNumEmbed != 0) { var entry = new FileIndexEntry(newRawOffsetWithDatNumEmbed, fileHash, folderHash); Index1Entries[folderHash].Add(fileHash, entry); } } else { if (newRawOffsetWithDatNumEmbed == 0) { Index1Entries[folderHash].Remove(fileHash); } else { originalOffset = Index1Entries[folderHash][fileHash].RawOffset; Index1Entries[folderHash][fileHash].RawOffset = newRawOffsetWithDatNumEmbed; } } if (!Index2Entries.ContainsKey(fullHash)) { if (newRawOffsetWithDatNumEmbed != 0) { var entry = new FileIndex2Entry(fullHash, newRawOffsetWithDatNumEmbed); Index2Entries.Add(fullHash, entry); } } else { if (newRawOffsetWithDatNumEmbed == 0) { Index2Entries.Remove(fullHash); } else { Index2Entries[fullHash].RawFileOffset = newRawOffsetWithDatNumEmbed; } } return(originalOffset); }
private void ReadIndex2File(BinaryReader stream) { stream.BaseStream.Seek(12, SeekOrigin.Begin); int headerSize = stream.ReadInt32(); stream.BaseStream.Seek(headerSize, SeekOrigin.Begin); Index2TotalSegmentHeaderSize = stream.ReadUInt32(); for (int segmentId = 0; segmentId < 4; segmentId++) { // For some reason segment 0 has 4 bytes more padding var offset = (segmentId * 72) + (headerSize + 4); if (segmentId > 0) { offset += 4; } stream.BaseStream.Seek(offset, SeekOrigin.Begin); // 12 Bytes of metadata Index2SegmentUnknowns.Add(stream.ReadInt32()); int segmentOffset = stream.ReadInt32(); int segmentSize = stream.ReadInt32(); // Next 20 bytes is the SHA-1 of the segment header. // (Don't need to read b/c we recalculat it on writing anyways) // Time to read the actual segment data. stream.BaseStream.Seek(segmentOffset, SeekOrigin.Begin); if (segmentId == 0) { for (int x = 0; x < segmentSize; x += 8) { FileIndex2Entry entry; entry = new FileIndex2Entry(); var bytes = stream.ReadBytes(8); entry.SetBytes(bytes); if (!Index2Entries.ContainsKey(entry.FullPathHash)) { Index2Entries.Add(entry.FullPathHash, entry); } } } else if (segmentId == 1 || segmentId == 2 || segmentId == 3) { Index2ExtraSegments.Add(stream.ReadBytes(segmentSize)); } } // Copy the original header in so we have it for later. stream.BaseStream.Seek(0, SeekOrigin.Begin); var header = stream.ReadBytes(headerSize); Index2Header = header; }