protected virtual IEnumerable <ProxyPathTableEntry> ReadPathTableEntries(Stream source, uint offset, uint length) { var entries = new List <ProxyPathTableEntry>(); source.Seek(offset, SeekOrigin.Begin); uint sectionEnd = offset + length; while (source.Position < sectionEnd) { var path = MiscUtilities.ReadString(source, false); int skipSize = (int)ProxyPathTableEntry.EntryLength - 8 - path.Length; source.Seek(skipSize, SeekOrigin.Current); byte[] hash = new byte[8]; source.Read(hash, 0, hash.Length); entries.Add(new ProxyPathTableEntry() { Path = path, Hash = hash, }); } return(entries); }
/// <remarks> /// Method based on enohka's code. /// See more at: http://github.com/enohka/moddingSuite /// </remarks> protected virtual void WriteDictionary(Stream target, EdataFile edataFile) { var sourceEdataHeader = edataFile.Header; var contentFilesDict = edataFile .ContentFiles .OfType <EdataContentFile>() .ToDictionary(x => x.Id); target.Seek(sourceEdataHeader.DictOffset, SeekOrigin.Begin); long dictEnd = sourceEdataHeader.DictOffset + sourceEdataHeader.DictLength; uint id = 0; //Odtworzenie słownika while (target.Position < dictEnd) { var buffer = new byte[4]; target.Read(buffer, 0, 4); int fileGroupId = BitConverter.ToInt32(buffer, 0); if (fileGroupId == 0) { EdataContentFile curFile = contentFilesDict[id]; // FileEntrySize target.Seek(4, SeekOrigin.Current); buffer = BitConverter.GetBytes(curFile.Offset); target.Write(buffer, 0, buffer.Length); buffer = BitConverter.GetBytes(curFile.Size); target.Write(buffer, 0, buffer.Length); byte[] checkSum = curFile.Checksum; target.Write(checkSum, 0, checkSum.Length); string name = MiscUtilities.ReadString(target); if ((name.Length + 1) % 2 == 1) { target.Seek(1, SeekOrigin.Current); } id++; } else if (fileGroupId > 0) { target.Seek(4, SeekOrigin.Current); string name = MiscUtilities.ReadString(target); if ((name.Length + 1) % 2 == 1) { target.Seek(1, SeekOrigin.Current); } } } target.Seek(sourceEdataHeader.DictOffset, SeekOrigin.Begin); var dictBuffer = new byte[sourceEdataHeader.DictLength]; target.Read(dictBuffer, 0, dictBuffer.Length); //Overwriting checksum byte[] dictCheckSum = MD5.Create().ComputeHash(dictBuffer); target.Seek(0x31, SeekOrigin.Begin); target.Write(dictCheckSum, 0, dictCheckSum.Length); }
/// <summary> /// Reads Edata version 2 dictionary entries /// </summary> /// <param name="source"></param> /// <param name="header"></param> /// <param name="token"></param> /// <returns></returns> protected virtual EdataDictionaryRootEntry ReadDcitionaryEntries( Stream source, uint dictOffset, uint dictLength) { EdataDictionaryRootEntry dictRoot = new EdataDictionaryRootEntry(); EdataDictionaryDirEntry workingDir = null; source.Seek(dictOffset + dictRoot.Length, SeekOrigin.Begin); long dictEnd = dictOffset + dictLength; while (source.Position < dictEnd) { var buffer = new byte[4]; source.Read(buffer, 0, 4); int entrysFirstFour = BitConverter.ToInt32(buffer, 0); source.Read(buffer, 0, 4); int entrysSecondFour = BitConverter.ToInt32(buffer, 0); bool isFileEntry = (entrysFirstFour == 0); if (isFileEntry) { int entryLength = entrysSecondFour; //source.Read(buffer, 0, 4); //int relevanceLength = BitConverter.ToInt32(buffer, 0); buffer = new byte[8]; source.Read(buffer, 0, buffer.Length); long offset = BitConverter.ToInt64(buffer, 0); source.Read(buffer, 0, buffer.Length); long length = BitConverter.ToInt64(buffer, 0); var checksum = new byte[16]; source.Read(checksum, 0, checksum.Length); String pathPart = MiscUtilities.ReadString(source); if (pathPart.Length % 2 == 0) { source.Seek(1, SeekOrigin.Current); } var newFile = new EdataDictionaryFileEntry(pathPart, entryLength, offset, length, checksum); if (workingDir != null) { workingDir.AddFollowingEntry(newFile); //Usuwamy tylko jeśli pojawia się wpis pliku oznaczony jako kończący ścieżkę. if (newFile.IsEndingEntry()) { EdataDictionaryDirEntry previousEntry = null; do { previousEntry = workingDir; workingDir = workingDir.PrecedingEntry as EdataDictionaryDirEntry; }while (workingDir != null && previousEntry.IsEndingEntry()); } } else { dictRoot.AddFollowingEntry(newFile); } } else //isDirEntry { int entryLength = entrysFirstFour; int relevanceLength = entrysSecondFour; //source.Read(buffer, 0, 4); //int relevanceLength = BitConverter.ToInt32(buffer, 0); String pathPart = MiscUtilities.ReadString(source); if (pathPart.Length % 2 == 0) { source.Seek(1, SeekOrigin.Current); } var newDir = new EdataDictionaryDirEntry(pathPart, entryLength, relevanceLength); if (workingDir != null) { workingDir.AddFollowingEntry(newDir); } else { dictRoot.AddFollowingEntry(newDir); } workingDir = newDir; } } return(dictRoot); }