Пример #1
0
        /// <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)));
        }
Пример #5
0
        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);
            }
        }
Пример #10
0
        public EdataManager ReadPackage(string file)
        {
            EdataContentFile contentfile = Files.Find(x => x.Path == file);

            if (contentfile != null)
            {
                try
                {
                    return(ParseRawData(GetRawData(contentfile)));
                }
                catch
                {
                }
            }
            return(null);
        }
Пример #11
0
        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();
        }
Пример #13
0
        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));
            }
        }
Пример #15
0
        /// <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();
        }
Пример #18
0
        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);
        }
Пример #20
0
        /// <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);
        }
Пример #21
0
        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);
        }
Пример #22
0
        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);
        }
Пример #24
0
        /// <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);
        }
Пример #25
0
        /// <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());
                }
            }
        }
Пример #26
0
        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);
        }
Пример #27
0
        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);
        }