/// <summary> /// Replaces a file in the current Edata package and saves the changes back. /// </summary> /// <param name="oldFile">The EdataFile object which is to be replaced.</param> /// <param name="newContent">The data of the new File including Header and content.</param> public virtual void ReplaceFile(EdataContentFile oldFile, byte[] newContent) { if (!File.Exists(FilePath)) { throw new InvalidOperationException("The Edata file does not exist anymore."); } string newFile; switch (Header.Version) { case 1: newFile = ReplaceRebuildV1(oldFile, newContent); break; case 2: newFile = ReplaceRebuildV2(oldFile, newContent); break; default: throw new NotSupportedException(string.Format("Edata Version {0} is currently not supported", Header.Version)); } var oldFileInfo = new FileInfo(FilePath); var backupFile = Path.Combine(oldFileInfo.DirectoryName, "to_delete.dat"); File.Move(FilePath, backupFile); File.Move(newFile, FilePath); File.Delete(backupFile); }
/// <summary> /// /// </summary> /// <param name="source"></param> /// <param name="dictionaryRoot"></param> /// <param name="contentFilesSectionOffset"></param> /// <returns></returns> protected virtual IEnumerable <EdataContentFile> TranslateDictionaryEntriesToContentFiles( Stream source, uint contentFilesSectionOffset, EdataDictionaryRootEntry dictionaryRoot) { var contentFiles = new List <EdataContentFile>(); var fileEntries = dictionaryRoot.SelectEntriesOfType <EdataDictionaryFileEntry>(); foreach (var entry in fileEntries) { var newCotnetFile = new EdataContentFile(); newCotnetFile.Offset = entry.FileOffset; newCotnetFile.TotalOffset = entry.FileOffset + contentFilesSectionOffset; newCotnetFile.Length = entry.FileLength; newCotnetFile.Checksum = entry.FileChecksum; newCotnetFile.Path = entry.FullPath; //To można by stąd wydzielić ResolveContentFileType(source, newCotnetFile, contentFilesSectionOffset); contentFiles.Add(newCotnetFile); } return(contentFiles); }
/// <summary> /// Reads the raw data of a file inside the current package. /// </summary> /// <param name="ofFile">A EdataFile of the current manager</param> /// <returns>The data of the desired EdataFile.</returns> public byte[] GetContentFileRawData(EdataContentFile ofFile) { if (ofFile.Manager != this) { throw new ArgumentException("oFile must be created by this instance of EdataManager"); } byte[] buffer; if (string.IsNullOrEmpty(FilePath)) { using (MemoryStream stream = new MemoryStream(Data, false)) { long offset = Header.FileOffset + ofFile.Offset; stream.Seek(offset, SeekOrigin.Begin); buffer = new byte[ofFile.Size]; stream.Read(buffer, 0, buffer.Length); } } else { using (var fs = new FileStream(FilePath, FileMode.Open)) { long offset = Header.FileOffset + ofFile.Offset; fs.Seek(offset, SeekOrigin.Begin); buffer = new byte[ofFile.Size]; fs.Read(buffer, 0, buffer.Length); } } return(buffer); }
public TradManager ReadDictionary(string fileName) { EdataContentFile thisFile = Files.Find(x => x.Path == fileName); if (thisFile == null) { throw new Exception("No content file has that name in these data : " + fileName); } return(new TradManager(GetRawData(thisFile))); }
private void SaveCommandExecute(object obj) { byte[] newFile = Manager.BuildTradFile(); OwnerVm.EdataManager.ReplaceFile(OwnerFile, newFile); OwnerVm.LoadFile(OwnerVm.LoadedFile); EdataContentFile newOwen = OwnerVm.EdataManager.Files.Single(x => x.Path == OwnerFile.Path); OwnerFile = newOwen; }
private void ResolveContentFileType( Stream source, EdataContentFile file, uint contentFilesSectionOffset) { source.Seek(file.Offset + contentFilesSectionOffset, SeekOrigin.Begin); var headerBuffer = new byte[12]; source.Read(headerBuffer, 0, headerBuffer.Length); file.FileType = GetFileTypeFromHeaderData(headerBuffer); }
public ScenarioEditorViewModel(EdataContentFile file, EdataFileViewModel ownerVm) { OwnerFile = file; EdataFileViewModel = ownerVm; var reader = new ScenarioReader(); ScenarioFile = reader.Read(ownerVm.EdataManager.GetRawData(file)); EditGameModeLogicCommand = new ActionCommand(EditGameModeLogicExecute); ZoneEditorCommand = new ActionCommand(ZoneEditorExecute); SaveCommand = new ActionCommand(SaveExecute); }
public NdfbinManager ReadNdfbin(string fileName) { EdataContentFile thisFile = Files.Find(x => x.Path == fileName); if (thisFile == null) { throw new Exception("No content file has that name in these data : " + fileName); } NdfbinManager ndfbin = new NdfbinManager(GetRawData(thisFile)); ndfbin.Initialize(); return(ndfbin); }
/// <summary> /// Replaces a file in the current Edata package and saves the changes back. /// </summary> /// <param name="oldFile">The EdataFile object which is to be replaced.</param> /// <param name="newContent">The data of the new File including Header and content.</param> public void ReplaceFile(EdataContentFile oldFile, byte[] newContent) { var newCont = ReplaceRebuild(oldFile, newContent); if (!File.Exists(FilePath)) { throw new InvalidOperationException("The Edata file does not exist anymore."); } using (var fs = new FileStream(FilePath, FileMode.Truncate)) { fs.Write(newCont, 0, newCont.Length); } }
public EdataManager ReadPackage(string file) { EdataContentFile contentfile = Files.Find(x => x.Path == file); if (contentfile != null) { try { return(ParseRawData(GetRawData(contentfile))); } catch { } } return(null); }
public TradFileViewModel(EdataContentFile owner, EdataFileViewModel contentFile) { SaveCommand = new ActionCommand(SaveCommandExecute); CreateHashCommand = new ActionCommand(CreateHashExecute, CreateHashCanExecute); AddEntryCommand = new ActionCommand(AddEntryExecute); RemoveEntryCommand = new ActionCommand(RemoveEntryExecute); OwnerFile = owner; OwnerVm = contentFile; Manager = new TradManager(OwnerVm.EdataManager.GetRawData(OwnerFile)); Entries = Manager.Entries; TitleText = string.Format("Dictionary editor [{0}]", OwnerFile.Path); }
public NdfEditorMainViewModel(EdataContentFile contentFile, EdataFileViewModel ownerVm) { OwnerFile = contentFile; EdataFileViewModel = ownerVm; var ndfbinReader = new NdfbinReader(); NdfBinary = ndfbinReader.Read(ownerVm.EdataManager.GetRawData(contentFile)); //var ndfbinManager = new NdfbinManager(ownerVm.EdataManager.GetRawData(contentFile)); //NdfbinManager = ndfbinManager; //ndfbinManager.Initialize(); InitializeNdfEditor(); }
protected void ResolveFileType(FileStream fs, EdataContentFile file) { // save original offset long origOffset = fs.Position; fs.Seek(file.Offset + Header.FileOffset, SeekOrigin.Begin); var headerBuffer = new byte[12]; fs.Read(headerBuffer, 0, headerBuffer.Length); file.FileType = GetFileTypeFromHeaderData(headerBuffer); // set offset back to original fs.Seek(origOffset, SeekOrigin.Begin); }
/// <summary> /// Reads content described by the given content file, but doesn't assing it to that Content File. /// </summary> /// <param name="file"></param> /// <returns></returns> public byte[] ReadContent(EdataContentFile file) { if (file.Owner == null) { throw new ArgumentException(String.Format("'{0}' is not assigned to any Edata File Owner.", file), "file"); } var contentOwenr = file.Owner; if (!File.Exists(contentOwenr.Path)) { throw new IOException(String.Format("Edata content owner file '{0}' doesn't exist.", contentOwenr.Path)); } using (FileStream stream = File.OpenRead(contentOwenr.Path)) { return(ReadContent(stream, file.TotalOffset, file.Length)); } }
/// <summary> /// Reads the raw data of a file inside the current package. /// </summary> /// <param name="ofFile">A EdataFile of the current manager</param> /// <returns>The data of the desired EdataFile.</returns> public virtual byte[] GetRawData(EdataContentFile ofFile) { //if (ofFile.Manager != this) // throw new ArgumentException("ofFile must be created by this instance of EdataManager"); byte[] buffer; using (FileStream fs = File.Open(FilePath, FileMode.Open)) { long offset = Header.FileOffset + ofFile.Offset; fs.Seek(offset, SeekOrigin.Begin); buffer = new byte[ofFile.Size]; fs.Read(buffer, 0, buffer.Length); } return(buffer); }
protected override void ExecuteCommandsLogic(CmdsExecutionData data) { if (!data.ContainerFile.ContainsContentFileWithPath(data.ContentPath)) { TgvImage image = DDSFileToTgv(data.ModificationSourcePath, !Command.UseMipMaps); //Trzeba mieć na to oko, czy nie powoduje problemów, bo przy replace była używana checksuma starego obrazka. image.SourceChecksum = !String.IsNullOrEmpty(Command.Checksum) ? MiscUtilities.HexByteStringToByteArray(Command.Checksum) : image.ComputeContentChecksum(); image.IsCompressed = Command.UseCompression; var newContentFile = new EdataContentFile(); newContentFile.Path = data.ContentPath; newContentFile.LoadCustomContent(TgvToBytes(image, !Command.UseMipMaps)); data.ContainerFile.AddContentFile(newContentFile); } else if (Command.OverwriteIfExist) { var contentFile = data.ContainerFile.GetContentFileByPath(data.ContentPath); //To nie będzie potrzebne tutaj jeśli nie bedzie trzeba ładować i wykorzystywać starego obrazka. if (contentFile.FileType != ContentFileType.Image) { throw new CmdExecutionFailedException( String.Format("Invalid targetContentPath: \"{0}\". It doesn't target an image content file.", data.ContentPath), DefaultExecutionErrorMsg); } //Ładowanie starego obrazka nie będzie potrzebne jeśli bedzie pewnośc ze recznie wygenerowana checkusma jest ok. //Ok, tu kiedyś było odczytywanie starych danych z starego obrazka, teraz checksuma jest generowana na nowo, //żeby uniknac konieczności ładowania tych starych danych, bo nie sa potrzeben przy dodawaniu, a tutaj były by potrzebne //i trudno to rozwiązać przy założeniu ze dane są ładowane na zewnątrz. //TgvImage oldTgv = BytesToTgv(contentFile.Content); TgvImage image = DDSFileToTgv(data.ModificationSourcePath, !Command.UseMipMaps); image.SourceChecksum = !String.IsNullOrEmpty(Command.Checksum) ? MiscUtilities.HexByteStringToByteArray(Command.Checksum) : image.ComputeContentChecksum(); image.IsCompressed = Command.UseCompression; contentFile.LoadCustomContent(TgvToBytes(image, !Command.UseMipMaps)); } }
private void SaveExecute(object obj) { if (zoneEditor != null) { zoneEditor.Save(); } Dispatcher dispatcher = Dispatcher.CurrentDispatcher; Action <string> report = msg => StatusText = msg; var s = new Task(() => { try { dispatcher.Invoke(() => IsUIBusy = true); dispatcher.Invoke(report, string.Format("Saving back changes...")); var writer = new ScenarioWriter(); byte[] newFile = writer.Write(ScenarioFile); dispatcher.Invoke(report, string.Format("Recompiling of {0} finished! ", EdataFileViewModel.EdataManager.FilePath)); EdataFileViewModel.EdataManager.ReplaceFile(OwnerFile, newFile); dispatcher.Invoke(report, "Replacing new File in edata finished!"); EdataFileViewModel.LoadFile(EdataFileViewModel.LoadedFile); EdataContentFile newOwen = EdataFileViewModel.EdataManager.Files.Single(x => x.Path == OwnerFile.Path); OwnerFile = newOwen; dispatcher.Invoke(report, string.Format("Saving of changes finished! {0}", EdataFileViewModel.EdataManager.FilePath)); } catch (Exception ex) { Trace.TraceError(string.Format("Error while saving scenario file: {0}", ex)); dispatcher.Invoke(report, "Saving interrupted - Did you start Wargame before I was ready?"); } finally { dispatcher.Invoke(() => IsUIBusy = false); } }); s.Start(); }
protected override void ExecuteCommandsLogic(CmdsExecutionData data) { if (!data.ContainerFile.ContainsContentFileWithPath(data.ContentPath)) { var newContentFile = new EdataContentFile(); newContentFile.Path = data.ContentPath; var content = (new ContentFileReader()).Read(data.ModificationSourcePath); newContentFile.LoadCustomContent(content); data.ContainerFile.AddContentFile(newContentFile); } else if (Command.OverwriteIfExist) { var contentFile = data.ContainerFile.GetContentFileByPath(data.ContentPath); var content = (new ContentFileReader()).Read(data.ModificationSourcePath); contentFile.LoadCustomContent(content); } }
protected long GetSpaceSizeForFile(EdataContentFile file) { long contentSize = file.IsContentLoaded ? file.ContentSize : file.Size; long contentSizeSupplTo16 = MathUtilities.SupplementTo(contentSize, 16); double spaceToSizeCoeff = 0.002; long spaceSize = (long)(contentSize * spaceToSizeCoeff); spaceSize = MathUtilities.RoundUpToMultiple(spaceSize, 16); spaceSize = MathUtilities.Clamp(spaceSize, MinBytesBetweenFiles, MaxBytesBetweenFiles); //If space size + contentSizeSupplement is bigger than Max, subtracting 16 is enough, bcos //contentSizeSupplement wont be never bigger than 16. spaceSize = (spaceSize + contentSizeSupplTo16 > MaxBytesBetweenFiles) ? spaceSize + contentSizeSupplTo16 - 16 : spaceSize + contentSizeSupplTo16; return(spaceSize); }
/// <summary> /// Load the first Mip Map from a Tgv file as a System.Drawing.Bitmap object /// </summary> /// <param name="file"></param> /// <param name="save"></param> /// <returns></returns> public bool TryToLoadDXT1Tgv(string file, out Bitmap bitmap) { EdataContentFile contentfile = Files.Find(x => x.Path == file); if (contentfile != null) { try { byte[] tgvdata = GetContentFileRawData(contentfile); TgvFile tgv = new TgvReader().Read(tgvdata); RawImage image = new TgvBitmapReader().GetDXT1Mip(tgv, 0); bitmap = image.GetBitmap(); return(true); } catch { } } bitmap = null; return(false); }
public int GetFileSize(EdataContentFile file) { int size = 0; // GroupSize size += 4; // Entry Size size += 4; // Zero terminated string size += file.Name.Length + 1; if (size % 2 == 1) { size++; } size += 8; size += 8; size += 16; return(size); }
protected override void ExecuteInternal(CmdExecutionContext context, CancellationToken?token = null) { CurrentStep = 0; CurrentMessage = Command.GetExecutionMessage(); //Cancel if requested; token.ThrowIfCanceledAndNotNull(); String sourceFullPath = Command.SourcePath.GetAbsoluteOrPrependIfRelative(context.InstallerSourceDirectory); if (!File.Exists(sourceFullPath)) { throw new CmdExecutionFailedException( String.Format("Command's source file \"{0}\" doesn't exist.", Command.SourcePath), String.Format(Properties.Resources.ReplaceImageErrorParametrizedMsg, Command.SourcePath)); } String targetfullPath = Command.TargetPath.GetAbsoluteOrPrependIfRelative(context.InstallerTargetDirectory); if (!File.Exists(targetfullPath)) { throw new CmdExecutionFailedException( String.Format("Command's target file \"{0}\" doesn't exist.", Command.TargetPath), String.Format(Properties.Resources.ReplaceImageErrorParametrizedMsg, Command.SourcePath)); } String contentPath = Command.NestedTargetPath.LastPart; if (contentPath == null) { throw new CmdExecutionFailedException( "Invalid command's TargetContentPath value.", String.Format(Properties.Resources.ReplaceImageErrorParametrizedMsg, Command.SourcePath)); } var edataFileReader = new EdataFileReader(); var contentOwningEdata = CanGetEdataFromContext(context) ? GetEdataFromContext(context) : edataFileReader.Read(targetfullPath, false); EdataContentFile contentFile = contentOwningEdata.GetContentFileByPath(contentPath); if (!contentFile.IsContentLoaded) { edataFileReader.LoadContent(contentFile); } if (contentFile.FileType != EdataContentFileType.Image) { throw new CmdExecutionFailedException( "Invalid command's TargetContentPath value. It doesn't point to an image content.", String.Format(Properties.Resources.ReplaceImageErrorParametrizedMsg, Command.SourcePath)); } CurrentStep++; var modifiedImageContent = ModifyImageContent(contentFile.Content, sourceFullPath); contentFile.Content = modifiedImageContent; if (!CanGetEdataFromContext(context)) { SaveEdataFile(contentOwningEdata, token); } CurrentStep = TotalSteps; }
/// <summary> /// /// </summary> /// <param name="file"></param> public void LoadContent(EdataContentFile file) { var content = ReadContent(file); file.LoadOrginalContent(content); }
/// <summary> /// The only tricky part about that algorythm is that you have to skip one byte if the length of the File/Dir name PLUS nullbyte is an odd number. /// </summary> /// <returns>A Collection of the Files found in the Dictionary</returns> protected List <EdataContentFile> ReadEdatDictionary(byte[] rawdata) { var files = new List <EdataContentFile>(); //Current dirs var dirs = new List <EdataDir>(); var endings = new List <long>(); using (MemoryStream stream = new MemoryStream(rawdata, 0, rawdata.Length)) { stream.Seek(Header.DirOffset, SeekOrigin.Begin); long dirEnd = Header.DirOffset + Header.DirLengh; uint id = 0; while (stream.Position < dirEnd) { var buffer = new byte[4]; stream.Read(buffer, 0, 4); int fileGroupId = BitConverter.ToInt32(buffer, 0); if (fileGroupId == 0) { var file = new EdataContentFile(this); stream.Read(buffer, 0, 4); file.FileEntrySize = BitConverter.ToInt32(buffer, 0); buffer = new byte[8]; stream.Read(buffer, 0, buffer.Length); file.Offset = BitConverter.ToInt64(buffer, 0); stream.Read(buffer, 0, buffer.Length); file.Size = BitConverter.ToInt64(buffer, 0); var checkSum = new byte[16]; stream.Read(checkSum, 0, checkSum.Length); file.Checksum = checkSum; file.Name = Utils.ReadString(stream); file.Path = MergePath(dirs, file.Name); if ((file.Name.Length + 1) % 2 == 1) { stream.Seek(1, SeekOrigin.Current); } file.Id = id; id++; ResolveFileType(stream, file); files.Add(file); while (endings.Count > 0 && stream.Position == endings.Last()) { dirs.Remove(dirs.Last()); endings.Remove(endings.Last()); } } else if (fileGroupId > 0) { var dir = new EdataDir(this); stream.Read(buffer, 0, 4); dir.FileEntrySize = BitConverter.ToInt32(buffer, 0); if (dir.FileEntrySize != 0) { endings.Add(dir.FileEntrySize + stream.Position - 8); } else if (endings.Count > 0) { endings.Add(endings.Last()); } dir.Name = Utils.ReadString(stream); if ((dir.Name.Length + 1) % 2 == 1) { stream.Seek(1, SeekOrigin.Current); } dirs.Add(dir); } } } return(files); }
/// <summary> /// Replaces a file and rebuilds the Edata File with /// </summary> /// <param name="oldFile">The EdataFile object which is to be replaced.</param> /// <param name="newContent">The data of the new File including Header and content.</param> /// <returns>The data of the completly rebuilt EdataFile. This has to be saved back to the file.</returns> public byte[] ReplaceRebuild(EdataContentFile oldFile, byte[] newContent) { var reserveBuffer = new byte[200]; using (var fs = new FileStream(FilePath, FileMode.Open)) { using (var newFile = new MemoryStream()) { var headerPart = new byte[Header.FileOffset]; fs.Read(headerPart, 0, headerPart.Length); newFile.Write(headerPart, 0, headerPart.Length); fs.Seek(Header.FileOffset, SeekOrigin.Begin); uint filesContentLength = 0; foreach (var file in Files) { byte[] fileBuffer; var oldOffset = file.Offset; file.Offset = newFile.Position - Header.FileOffset; if (file == oldFile) { fileBuffer = newContent; file.Size = newContent.Length; } else { fileBuffer = new byte[file.Size]; fs.Seek(oldOffset + Header.FileOffset, SeekOrigin.Begin); fs.Read(fileBuffer, 0, fileBuffer.Length); } file.Checksum = MD5.Create().ComputeHash(fileBuffer); newFile.Write(fileBuffer, 0, fileBuffer.Length); newFile.Write(reserveBuffer, 0, reserveBuffer.Length); filesContentLength += (uint)fileBuffer.Length + (uint)reserveBuffer.Length; } newFile.Seek(0x25, SeekOrigin.Begin); newFile.Write(BitConverter.GetBytes(filesContentLength), 0, 4); newFile.Seek(Header.DirOffset, SeekOrigin.Begin); long dirEnd = Header.DirOffset + Header.DirLengh; uint id = 0; while (newFile.Position < dirEnd) { var buffer = new byte[4]; newFile.Read(buffer, 0, 4); int fileGroupId = BitConverter.ToInt32(buffer, 0); if (fileGroupId == 0) { var curFile = Files.Single(x => x.Id == id); // FileEntrySize newFile.Seek(4, SeekOrigin.Current); buffer = BitConverter.GetBytes(curFile.Offset); newFile.Write(buffer, 0, buffer.Length); buffer = BitConverter.GetBytes(curFile.Size); newFile.Write(buffer, 0, buffer.Length); var checkSum = curFile.Checksum; newFile.Write(checkSum, 0, checkSum.Length); var name = Utils.ReadString(newFile); if ((name.Length + 1) % 2 == 1) { newFile.Seek(1, SeekOrigin.Current); } id++; } else if (fileGroupId > 0) { newFile.Seek(4, SeekOrigin.Current); var name = Utils.ReadString(newFile); if ((name.Length + 1) % 2 == 1) { newFile.Seek(1, SeekOrigin.Current); } } } newFile.Seek(Header.DirOffset, SeekOrigin.Begin); var dirBuffer = new byte[Header.DirLengh]; newFile.Read(dirBuffer, 0, dirBuffer.Length); var dirCheckSum = MD5.Create().ComputeHash(dirBuffer); newFile.Seek(0x31, SeekOrigin.Begin); newFile.Write(dirCheckSum, 0, dirCheckSum.Length); return(newFile.ToArray()); } } }
protected string ReplaceRebuildV1(EdataContentFile oldFile, byte[] newContent) { //var reserveBuffer = new byte[200]; // RUSE doesn't like the reserve buffer between files. var tmp = new FileInfo(FilePath); var tmpPath = Path.Combine(tmp.DirectoryName, string.Format("{0}_{1}", tmp.FullName, "temp")); if (!File.Exists(tmpPath)) { using (File.Create(tmpPath)) { } } using (var fs = new FileStream(FilePath, FileMode.Open)) { using (var newFile = new FileStream(tmpPath, FileMode.Truncate)) { byte[] oldHead = new byte[Header.FileOffset]; fs.Read(oldHead, 0, (int)Header.FileOffset); newFile.Write(oldHead, 0, oldHead.Length); byte[] fileBuffer; uint filesContentLength = 0; // Write Filecontent and replace selected file foreach (var file in Files) { long oldOffset = file.Offset; file.Offset = newFile.Position - Header.FileOffset; if (file == oldFile) { fileBuffer = newContent; file.Size = newContent.Length; } else { fileBuffer = new byte[file.Size]; fs.Seek(oldOffset + Header.FileOffset, SeekOrigin.Begin); fs.Read(fileBuffer, 0, fileBuffer.Length); } newFile.Write(fileBuffer, 0, fileBuffer.Length); //newFile.Write(reserveBuffer, 0, reserveBuffer.Length); filesContentLength += (uint)fileBuffer.Length; // +(uint)reserveBuffer.Length; } newFile.Seek(Header.DictOffset, SeekOrigin.Begin); long dirEnd = Header.DictOffset + Header.DictLength; uint id = 0; var buffer = new byte[4]; while (newFile.Position < dirEnd) { newFile.Read(buffer, 0, 4); int fileGroupId = BitConverter.ToInt32(buffer, 0); if (fileGroupId == 0) { EdataContentFile curFile = Files[(int)id]; // FileEntrySize newFile.Seek(4, SeekOrigin.Current); buffer = BitConverter.GetBytes((uint)curFile.Offset); newFile.Write(buffer, 0, buffer.Length); buffer = BitConverter.GetBytes((uint)curFile.Size); newFile.Write(buffer, 0, buffer.Length); newFile.Seek(1, SeekOrigin.Current); string name = Utils.ReadString(newFile); if ((name.Length + 1) % 2 == 0) { newFile.Seek(1, SeekOrigin.Current); } id++; } else if (fileGroupId > 0) { newFile.Seek(4, SeekOrigin.Current); string name = Utils.ReadString(newFile); if ((name.Length + 1) % 2 == 1) { newFile.Seek(1, SeekOrigin.Current); } } } newFile.Seek(Header.DictOffset, SeekOrigin.Begin); var dirBuffer = new byte[Header.DictLength]; newFile.Read(dirBuffer, 0, dirBuffer.Length); byte[] dirCheckSum = MD5.Create().ComputeHash(dirBuffer); newFile.Seek(8, SeekOrigin.Begin); newFile.Write(dirCheckSum, 0, dirCheckSum.Length); newFile.Seek(13, SeekOrigin.Current); newFile.Write(BitConverter.GetBytes(filesContentLength), 0, 4); } } return(tmpPath); }
protected ObservableCollection <EdataContentFile> ReadEdatV1Dictionary() { var files = new ObservableCollection <EdataContentFile>(); var dirs = new List <EdataDir>(); var endings = new List <long>(); using (FileStream fileStream = File.Open(FilePath, FileMode.Open)) { fileStream.Seek(Header.DictOffset, SeekOrigin.Begin); long dirEnd = Header.DictOffset + Header.DictLength; uint id = 0; while (fileStream.Position < dirEnd) { var buffer = new byte[4]; fileStream.Read(buffer, 0, 4); int fileGroupId = BitConverter.ToInt32(buffer, 0); if (fileGroupId == 0) { var file = new EdataContentFile(); fileStream.Read(buffer, 0, 4); file.FileEntrySize = BitConverter.ToInt32(buffer, 0); //buffer = new byte[8]; - it's [4] now, so no need to change fileStream.Read(buffer, 0, 4); file.Offset = BitConverter.ToUInt32(buffer, 0); fileStream.Read(buffer, 0, 4); file.Size = BitConverter.ToUInt32(buffer, 0); //var checkSum = new byte[16]; //fileStream.Read(checkSum, 0, checkSum.Length); //file.Checksum = checkSum; fileStream.Seek(1, SeekOrigin.Current); //instead, skip 1 byte - as in WEE DAT unpacker file.Name = Utils.ReadString(fileStream); file.Path = MergePath(dirs, file.Name); if ((file.Name.Length + 1) % 2 == 0) { fileStream.Seek(1, SeekOrigin.Current); } file.Id = id; id++; ResolveFileType(fileStream, file); files.Add(file); while (endings.Count > 0 && fileStream.Position == endings.Last()) { dirs.Remove(dirs.Last()); endings.Remove(endings.Last()); } } else if (fileGroupId > 0) { var dir = new EdataDir(); fileStream.Read(buffer, 0, 4); dir.FileEntrySize = BitConverter.ToInt32(buffer, 0); if (dir.FileEntrySize != 0) { endings.Add(dir.FileEntrySize + fileStream.Position - 8); } else if (endings.Count > 0) { endings.Add(endings.Last()); } dir.Name = Utils.ReadString(fileStream); if ((dir.Name.Length + 1) % 2 == 1) { fileStream.Seek(1, SeekOrigin.Current); } dirs.Add(dir); } } } return(files); }
/// <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); }