Пример #1
0
 public FormInfo(IStateInfo stateInfo, IFormCommunicator formCommunicator, IProgressContext progress, ILogger logger)
 {
     StateInfo        = stateInfo;
     FormCommunicator = formCommunicator;
     Progress         = progress;
     Logger           = logger;
 }
Пример #2
0
        private static void WipeFile(FileLock fileLock, IProgressContext progress)
        {
            if (!fileLock.DataStore.IsAvailable)
            {
                if (Resolve.Log.IsInfoEnabled)
                {
                    Resolve.Log.LogInfo("Found '{0}' to be already deleted.".InvariantFormat(fileLock.DataStore.FullName));
                }
                return;
            }

            if (Resolve.Log.IsInfoEnabled)
            {
                Resolve.Log.LogInfo("Wiping '{0}'.".InvariantFormat(fileLock.DataStore.FullName));
            }

            if (fileLock.DataStore.IsWriteProtected)
            {
                fileLock.DataStore.IsWriteProtected = false;
            }
            New <AxCryptFile>().Wipe(fileLock, progress);

            if (Resolve.Log.IsInfoEnabled)
            {
                Resolve.Log.LogInfo("Wiped '{0}'.".InvariantFormat(fileLock.DataStore.FullName));
            }
        }
Пример #3
0
        private Bitmap DecodeColorInternal(byte[] data, Size imageSize, IProgressContext progress)
        {
            // Prepare information and instances
            var paddedSize  = GetPaddedSize(imageSize);
            var swizzle     = GetPixelRemapper(_colorEncoding, paddedSize);
            var finalSize   = GetFinalSize(paddedSize, swizzle);
            var colorShader = _shadeColorsFunc?.Invoke();

            // Load colors
            var colorCount       = data.Length * 8 / _colorEncoding.BitsPerValue * _colorEncoding.ColorsPerValue;
            var colorCountBySize = finalSize.Width * finalSize.Height;

            // HINT: If the data portion does not fit with the actual image size, it will cause progress irregularities.
            //       If the given data is shorter than what is needed for the full image, we throw.
            //       Otherwise enough data is given and the image can be fully decoded, even if excess data is not used.
            if (colorCount < colorCountBySize)
            {
                throw new InvalidOperationException("Given data is too short.");
            }

            var setMaxProgress = progress?.SetMaxValue(colorCountBySize * _colorEncoding.ColorsPerValue);
            var colors         = _colorEncoding
                                 .Load(data, new EncodingLoadContext(finalSize, _taskCount))
                                 .AttachProgress(setMaxProgress, "Decode colors");

            // Apply color shader
            if (colorShader != null)
            {
                colors = colors.Select(colorShader.Read);
            }

            // Create image with unpadded dimensions
            return(colors.ToBitmap(imageSize, paddedSize, swizzle, _anchor));
        }
Пример #4
0
        private Bitmap DecodeImage(IProgressContext progress = null)
        {
            if (_decodedImage != null)
            {
                return(_decodedImage);
            }

            Func <Bitmap> decodeImageAction;

            if (IsIndexed)
            {
                var transcoder = ImageConfiguration.Clone()
                                 .TranscodeWith(size => _imageState.SupportedIndexEncodings[_imageInfo.ImageFormat].Encoding)
                                 .TranscodePaletteWith(() => _imageState.SupportedPaletteEncodings[_imageInfo.PaletteFormat])
                                 .Build();

                decodeImageAction = () => transcoder.Decode(_imageInfo.ImageData, _imageInfo.PaletteData, _imageInfo.ImageSize, progress);
            }
            else
            {
                var transcoder = ImageConfiguration.Clone()
                                 .TranscodeWith(size => _imageState.SupportedEncodings[_imageInfo.ImageFormat])
                                 .Build();

                decodeImageAction = () => transcoder.Decode(_imageInfo.ImageData, _imageInfo.ImageSize, progress);
            }

            _decodedImage = decodeImageAction();
            if (_bestImage == null)
            {
                _bestImage = _decodedImage;
            }

            return(_decodedImage);
        }
Пример #5
0
        public static void WithTask(this IProgressContext ctx, string description, Action <IProgressTask> predicate)
        {
            var task = ctx.AddTask(description);

            predicate(task);
            task.StopTask();
        }
        private Task <FileOperationContext> OpenEncryptedWorkAsync(IDataStore file, IProgressContext progress)
        {
            FileOperationsController operationsController = new FileOperationsController(progress);

            operationsController.QueryDecryptionPassphrase = HandleQueryOpenPassphraseEventAsync;

            operationsController.KnownKeyAdded = new AsyncDelegateAction <FileOperationEventArgs>(async(FileOperationEventArgs e) =>
            {
                if (!_fileSystemState.KnownPassphrases.Any(i => i.Thumbprint == e.LogOnIdentity.Passphrase.Thumbprint))
                {
                    _fileSystemState.KnownPassphrases.Add(e.LogOnIdentity.Passphrase);
                }
                await _knownIdentities.AddAsync(e.LogOnIdentity);
            });

            operationsController.SetConvertLegacyOptionCommandAsync = async() =>
            {
                if (Resolve.UserSettings.EncryptionUpgradeMode != EncryptionUpgradeMode.NotDecided)
                {
                    return;
                }
                if (!New <LicensePolicy>().Capabilities.Has(LicenseCapability.EditExistingFiles))
                {
                    return;
                }

                bool autoConvert = await New <IPopup>().ShowAsync(PopupButtons.OkCancel, Texts.OptionsConvertMenuItemText, Texts.LegacyOpenMessage) == PopupButtons.Ok;

                autoConvert = autoConvert && New <IVerifySignInPassword>().Verify(Texts.LegacyConversionVerificationPrompt);
                New <UserSettings>().EncryptionUpgradeMode = autoConvert ? EncryptionUpgradeMode.AutoUpgrade : EncryptionUpgradeMode.RetainWithoutUpgrade;
            };
            return(operationsController.DecryptAndLaunchAsync(file));
        }
Пример #7
0
        public override long SaveFileData(Stream output, bool compress, IProgressContext progress = null)
        {
            // Write unchanged file
            if (!ContentChanged)
            {
                _origStream.Position = 0;
                _origStream.CopyTo(output);

                ContentChanged = false;
                return(_origStream.Length);
            }

            // Write newly chunked file
            FileData.Position = 0;
            var chunkedStreamData = ChunkStream.CreateChunked(FileData, _usesCompression, out var newChunks);

            chunkedStreamData.CopyTo(output);
            Chunks = newChunks;

            FileData.Position = 0;
            Entry.crc32       = Crc32.ComputeValue(FileData);

            ContentChanged = false;
            return(chunkedStreamData.Length);
        }
Пример #8
0
        public async Task Load(IFileSystem fileSystem, UPath filePath, ITemporaryStreamProvider temporaryStreamProvider,
                               IProgressContext progress)
        {
            var fileStream = await fileSystem.OpenFileAsync(filePath);

            Files = _pack.Load(fileStream);
        }
Пример #9
0
 public FormInfo(IFileState fileState, IFormCommunicator formCommunicator, IProgressContext progress, ILogger logger)
 {
     FileState        = fileState;
     FormCommunicator = formCommunicator;
     Progress         = progress;
     Logger           = logger;
 }
Пример #10
0
        private Bitmap DecodeImage(IProgressContext progress = null)
        {
            if (_decodedImage != null)
            {
                return(_decodedImage);
            }

            Func <Bitmap> decodeImageAction;

            if (IsIndexed)
            {
                var transcoder = CreateImageConfiguration(ImageFormat, PaletteFormat)
                                 .Transcode.With(_encodingDefinition.GetIndexEncoding(ImageFormat).IndexEncoding)
                                 .TranscodePalette.With(_encodingDefinition.GetPaletteEncoding(PaletteFormat))
                                 .Build();

                decodeImageAction = () => transcoder.Decode(ImageInfo.ImageData, ImageInfo.PaletteData, ImageInfo.ImageSize, progress);
            }
            else
            {
                var transcoder = CreateImageConfiguration(ImageFormat, PaletteFormat)
                                 .Transcode.With(_encodingDefinition.GetColorEncoding(ImageFormat))
                                 .Build();

                decodeImageAction = () => transcoder.Decode(ImageInfo.ImageData, ImageInfo.ImageSize, progress);
            }

            ExecuteActionWithProgress(() => _decodedImage = decodeImageAction(), progress);

            _bestImage ??= _decodedImage;

            return(_decodedImage);
        }
Пример #11
0
        private async Task <SaveResult> SaveAndReplaceStateAsync(IStateInfo stateInfo, IFileSystem destinationFileSystem, UPath savePath,
                                                                 IProgressContext progress)
        {
            var saveState = stateInfo.PluginState as ISaveFiles;

            // 1. Save state to a temporary destination
            var temporaryContainer = _streamMonitor.CreateTemporaryFileSystem();
            var saveStateResult    = await TrySaveState(saveState, temporaryContainer, savePath.GetName(), progress);

            if (!saveStateResult.IsSuccessful)
            {
                return(saveStateResult);
            }

            // TODO: If reload fails then the original files get closed already, which makes future save actions impossible due to disposed streams

            // 2. Dispose of all streams in this state
            _streamMonitor.GetStreamManager(temporaryContainer).ReleaseAll();
            stateInfo.StreamManager.ReleaseAll();

            // 3. Replace files in destination file system
            var moveResult = await MoveFiles(stateInfo, temporaryContainer, destinationFileSystem);

            if (!moveResult.IsSuccessful)
            {
                return(moveResult);
            }

            // 4. Release temporary destination
            _streamMonitor.ReleaseTemporaryFileSystem(temporaryContainer);

            return(SaveResult.SuccessfulResult);
        }
Пример #12
0
        /// <summary>
        /// Enumerate all files listed as active, checking for status changes and take appropriate actions such as updating status
        /// in the FileSystemState, re-encrypting or deleting temporary plaintext copies.
        /// </summary>
        /// <param name="_fileSystemState">The FileSystemState to enumerate and possibly update.</param>
        /// <param name="mode">Under what circumstances is the FileSystemState.Changed event raised.</param>
        /// <param name="progress">The ProgressContext to provide visual progress feedback via.</param>
        public virtual async Task CheckActiveFiles(IProgressContext progress)
        {
            if (progress == null)
            {
                throw new ArgumentNullException("progress");
            }

            progress.NotifyLevelStart();
            try
            {
                progress.AddTotal(Resolve.FileSystemState.ActiveFileCount);
                await Resolve.FileSystemState.ForEach(async (ActiveFile activeFile) =>
                {
                    try
                    {
                        activeFile = await CheckActiveFile(activeFile, progress).Free();
                        if (activeFile.Status == ActiveFileStatus.NotDecrypted && !activeFile.EncryptedFileInfo.IsAvailable)
                        {
                            activeFile = null;
                        }
                        return(activeFile);
                    }
                    finally
                    {
                        progress.AddCount(1);
                    }
                }).Free();
            }
            finally
            {
                progress.NotifyLevelFinished();
            }
        }
Пример #13
0
        /// <summary>
        /// Creates a new instance of <see cref="PluginManager"/>.
        /// </summary>
        /// <param name="progress">The progress context for plugin processes.</param>
        /// <param name="dialogManager">The dialog manager for plugin processes.</param>
        /// <param name="pluginPaths">The paths to search for plugins.</param>
        public PluginManager(IProgressContext progress, IDialogManager dialogManager, params string[] pluginPaths)
        {
            ContractAssertions.IsNotNull(progress, nameof(progress));
            ContractAssertions.IsNotNull(dialogManager, nameof(dialogManager));

            // 1. Setup all necessary instances
            _filePluginLoaders  = new IPluginLoader <IFilePlugin>[] { new CsFilePluginLoader(pluginPaths) };
            _gameAdapterLoaders = new IPluginLoader <IGameAdapter>[] { new CsGamePluginLoader(pluginPaths) };

            _progress      = progress;
            _dialogManager = dialogManager;

            LoadErrors = _filePluginLoaders.SelectMany(pl => pl.LoadErrors ?? Array.Empty <PluginLoadError>())
                         .Concat(_gameAdapterLoaders.SelectMany(pl => pl.LoadErrors ?? Array.Empty <PluginLoadError>()))
                         .DistinctBy(e => e.AssemblyPath)
                         .ToList();

            _streamMonitor = new StreamMonitor();

            _fileLoader = new FileLoader(_filePluginLoaders);
            _fileSaver  = new FileSaver(_streamMonitor, dialogManager);

            _fileLoader.OnManualSelection += FileLoader_OnManualSelection;

            _loadedFiles = new List <IStateInfo>();
        }
Пример #14
0
        private Bitmap DecodeColorInternal(byte[] data, Size imageSize, IProgressContext progress)
        {
            var paddedSize = _paddedSize?.Invoke(imageSize) ?? Size.Empty;
            var finalSize  = paddedSize.IsEmpty ? imageSize : paddedSize;

            var colorEncoding = _colorEncoding();

            // Load colors
            var valueCount       = data.Length * 8 / colorEncoding.BitsPerValue;
            var valueCountBySize = finalSize.Width * finalSize.Height / colorEncoding.ColorsPerValue;

            // HINT: If the data portion does not fit with the actual image size, it will cause progress irregularities.
            //       If the given data is shorter than what is needed  for the full image, we throw.
            //       Otherwise enough data is given and the image can be fully decoded, even if excess data is not used.
            if (valueCount < valueCountBySize)
            {
                throw new InvalidOperationException("Given data is too short.");
            }

            var setMaxProgress = progress?.SetMaxValue(valueCountBySize * colorEncoding.ColorsPerValue);
            var colors         = colorEncoding
                                 .Load(data, new EncodingLoadContext(imageSize, _taskCount))
                                 .AttachProgress(setMaxProgress, "Decode colors");

            // Create image with unpadded dimensions
            return(colors.ToBitmap(imageSize, paddedSize, _swizzle?.Invoke(finalSize)));
        }
        private Task <FileOperationContext> WipeFileWorkAsync(IDataStore file, IProgressContext progress)
        {
            FileOperationsController operationsController = new FileOperationsController(progress);

            operationsController.WipeQueryConfirmation += (object sender, FileOperationEventArgs e) =>
            {
                FileSelectionEventArgs fileSelectionArgs = new FileSelectionEventArgs(new string[] { file.FullName, })
                {
                    FileSelectionType = FileSelectionType.WipeConfirm,
                };
                OnSelectingFiles(fileSelectionArgs);
                e.Cancel           = fileSelectionArgs.Cancel;
                e.Skip             = fileSelectionArgs.Skip;
                e.ConfirmAll       = fileSelectionArgs.ConfirmAll;
                e.SaveFileFullName = fileSelectionArgs.SelectedFiles.FirstOrDefault() ?? String.Empty;
            };

            operationsController.Completed += async(object sender, FileOperationEventArgs e) =>
            {
                if (e.Skip)
                {
                    return;
                }
                if (e.Status.ErrorStatus == ErrorStatus.Success)
                {
                    await New <ActiveFileAction>().RemoveRecentFiles(new IDataStore[] { New <IDataStore>(e.SaveFileFullName) }, progress);
                }
            };

            return(operationsController.WipeFileAsync(file));
        }
Пример #16
0
        private byte[] EncodeColorInternal(Bitmap image, IProgressContext progress = null)
        {
            var paddedSize = _paddedSize?.Invoke(image.Size) ?? Size.Empty;
            var size       = paddedSize.IsEmpty ? image.Size : paddedSize;

            // If we have quantization enabled
            IEnumerable <Color> colors;

            if (_quantizer != null)
            {
                var scopedProgresses = progress?.SplitIntoEvenScopes(2);

                var(indices, palette) = QuantizeImage(image, paddedSize, scopedProgresses?[0]);

                // Recompose indices to colors
                var setMaxProgress = scopedProgresses?[1]?.SetMaxValue(image.Width * image.Height);
                colors = indices.ToColors(palette).AttachProgress(setMaxProgress, "Encode indices");
            }
            else
            {
                // Decompose image to colors
                var setMaxProgress = progress?.SetMaxValue(image.Width * image.Height);
                colors = image.ToColors(paddedSize, _swizzle?.Invoke(size)).AttachProgress(setMaxProgress, "Encode colors");
            }

            // Save color data
            return(_colorEncoding().Save(colors, new EncodingSaveContext(image.Size, _taskCount)));
        }
Пример #17
0
        public override long SaveFileData(Stream output, bool compress, IProgressContext progress = null)
        {
            var bkPos = output.Position;

            if (UsesCompression)
            {
                output.Position += 0x18;
            }

            var writtenSize = base.SaveFileData(output, compress, progress);

            if (!UsesCompression)
            {
                return(writtenSize);
            }

            writtenSize += 0x18;

            (bkPos, output.Position) = (output.Position, bkPos);

            WriteInt32(output, 0x18);
            WriteInt32(output, 0);
            WriteInt32(output, (int)writtenSize);
            WriteInt32(output, (int)FileSize);
            WriteInt32(output, 0);
            WriteInt32(output, 0);

            output.Position = bkPos;

            return(writtenSize);
        }
Пример #18
0
        /// <summary>
        /// Create a new instance of <see cref="ImageForm"/>.
        /// </summary>
        /// <param name="stateInfo">The loaded state for an image format.</param>
        /// <param name="formCommunicator"><see cref="IFormCommunicator"/> to allow communication with the main form.</param>
        /// <param name="progressContext">The progress context.</param>
        /// <exception cref="T:System.InvalidOperationException">If state is not an image state.</exception>
        public ImageForm(IStateInfo stateInfo, IFormCommunicator formCommunicator, IProgressContext progressContext)
        {
            InitializeComponent();

            if (!(stateInfo.PluginState is IImageState imageState))
            {
                throw new InvalidOperationException($"This state is not an {nameof(IImageState)}.");
            }

            ContractAssertions.IsNotNull(stateInfo, nameof(stateInfo));
            ContractAssertions.IsNotNull(imageState.Images, nameof(imageState.Images));

            // Check integrity of the image state
            CheckIntegrity(imageState);

            _stateInfo        = stateInfo;
            _formCommunicator = formCommunicator;
            _progressContext  = progressContext;

            imbPreview.Image = ImageState.Images.FirstOrDefault()?.GetImage(progressContext);

            // Populate format dropdown
            PopulateFormatDropdown();

            // Populate palette format dropdown
            PopulatePaletteDropdown(imageState.Images[_selectedImageIndex]);

            // Populate border style drop down
            PopulateBorderStyleDropdown();

            // Update form elements
            UpdateFormInternal();
            UpdatePreview();
            UpdateImageList();
        }
Пример #19
0
        /// <summary>
        /// Decode given palette data without buffering.
        /// </summary>
        /// <param name="paletteData">Palette data to decode.</param>
        /// <param name="context"></param>
        /// <returns>Decoded palette.</returns>
        private IList <Color> DecodePalette(byte[] paletteData, IProgressContext context = null)
        {
            var paletteEncoding = EncodingDefinition.GetPaletteEncoding(PaletteFormat);

            return(paletteEncoding
                   .Load(paletteData, new EncodingLoadContext(new Size(1, paletteData.Length * 8 / paletteEncoding.BitsPerValue), TaskCount))
                   .ToArray());
        }
Пример #20
0
        public ConsoleDialogManager(IArgumentGetter argumentGetter, IProgressContext progress)
        {
            ContractAssertions.IsNotNull(argumentGetter, nameof(argumentGetter));
            ContractAssertions.IsNotNull(progress, nameof(progress));

            _argumentGetter = argumentGetter;
            _progress       = progress;
        }
Пример #21
0
        public static async Task <T> WithTaskAsync <T>(this IProgressContext ctx, string description, Func <IProgressTask, Task <T> > predicate)
        {
            var task   = ctx.AddTask(description);
            var result = await predicate(task);

            task.StopTask();
            return(result);
        }
Пример #22
0
        public static async Task WithTaskAsync(this IProgressContext ctx, string description, Func <IProgressTask, Task> predicate)
        {
            var task = ctx.AddTask(description);

            await predicate(task);

            task.StopTask();
        }
Пример #23
0
        protected BaseContext(IProgressContext progressContext)
        {
            ContractAssertions.IsNotNull(progressContext, nameof(progressContext));

            Progress = progressContext;

            _commands = InitializeCommands();
        }
Пример #24
0
        public Task Save(IFileSystem fileSystem, UPath savePath, IProgressContext progress)
        {
            var fileStream = fileSystem.OpenFile(savePath, FileMode.Create);

            _pack.Save(fileStream, Files);

            return(Task.CompletedTask);
        }
Пример #25
0
        protected BaseFileContext(IInternalFileManager pluginManager, IProgressContext progressContext) :
            base(progressContext)
        {
            ContractAssertions.IsNotNull(progressContext, nameof(progressContext));

            PluginManager = pluginManager;

            ContextNode = new ContextNode();
        }
Пример #26
0
        public void TranscodeImage(int imageFormat, IProgressContext progress = null)
        {
            if (IsImageLocked)
            {
                throw new InvalidOperationException("Image cannot be transcoded to another format.");
            }

            throw new InvalidOperationException("Transcoding image is not supported for bitmaps.");
        }
Пример #27
0
        /// <summary>
        /// Decode current palette from <see cref="ImageInfo"/>.
        /// </summary>
        /// <param name="context"></param>
        /// <returns>Either buffered palette or decoded palette.</returns>
        private IList <Color> DecodePalette(IProgressContext context = null)
        {
            if (_decodedPalette != null)
            {
                return(_decodedPalette);
            }

            return(_decodedPalette = DecodePalette(ImageInfo.PaletteData, context));
        }
Пример #28
0
        public void Save(Stream output, IList <ArchiveFileInfo> files, IProgressContext progress)
        {
            if (_xfsaParser == null)
            {
                throw new InvalidOperationException("No XFSA is loaded.");
            }

            _xfsaParser.Save(output, files, progress);
        }
Пример #29
0
        public TextContext(IFileState stateInfo, IContext parentContext, IProgressContext progressContext) :
            base(progressContext)
        {
            ContractAssertions.IsNotNull(stateInfo, nameof(stateInfo));
            ContractAssertions.IsNotNull(parentContext, nameof(parentContext));

            _stateInfo     = stateInfo;
            _parentContext = parentContext;
        }
Пример #30
0
        public override long SaveFileData(Stream output, bool compress, IProgressContext progress = null)
        {
            var writtenSize = base.SaveFileData(output, compress, progress);

            while (output.Position % 4 != 0)
                output.WriteByte(0);

            return writtenSize;
        }