Exemple #1
0
 public ArchiveFileItem(IArchiveDataManager manager, string fileName, string directory, object archiveEntry)
 {
     Manager      = manager;
     FileName     = fileName;
     Directory    = directory;
     ArchiveEntry = archiveEntry;
 }
Exemple #2
0
    public override bool IsOfType(ArchiveFileStream inputStream, IArchiveDataManager manager, TextureCooked?tex)
    {
        UbiArtSettings settings = manager.Context !.GetSettings <UbiArtSettings>();

        // TODO: Find better way to check this
        return(settings.Platform == Platform.Xbox360);
    }
Exemple #3
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="manager">The manager</param>
 public ArchiveCreatorDialogViewModel(IArchiveDataManager manager)
 {
     // Set properties
     Title         = Resources.Archive_CreateHeader;
     Manager       = manager;
     DisplayStatus = String.Empty;
 }
Exemple #4
0
    public async Task OpenArchiveExplorerAsync()
    {
        // Allow the user to select the files
        FileBrowserResult fileResult = await Services.BrowseUI.BrowseFileAsync(new FileBrowserViewModel()
        {
            Title            = Resources.Utilities_ArchiveExplorer_FileSelectionHeader,
            DefaultDirectory = SelectedType.Modes.SelectedValue.GetAttribute <GameModeBaseAttribute>()?.Game?.GetInstallDir(false).FullPath,
            ExtensionFilter  = SelectedType.FileExtension.GetFileFilterItem.ToString(),
            MultiSelection   = true,
        });

        if (fileResult.CanceledByUser)
        {
            return;
        }

        // Get the manager
        using IArchiveDataManager manager = SelectedType.GetManager(Utility_Archives_TypeViewModel.ArchiveMode.Explorer);

        try
        {
            // Show the Archive Explorer
            await Services.UI.ShowArchiveExplorerAsync(manager, fileResult.SelectedFiles.ToArray());
        }
        catch (Exception ex)
        {
            Logger.Error(ex, "Archive explorer");

            await Services.MessageUI.DisplayExceptionMessageAsync(ex, Resources.Archive_CriticalError);
        }
    }
Exemple #5
0
    public async Task CreateArchiveAsync()
    {
        // Get the manager
        using IArchiveDataManager manager = SelectedType.GetManager(Utility_Archives_TypeViewModel.ArchiveMode.Explorer);

        // Show the Archive Creator
        await Services.UI.ShowArchiveCreatorAsync(manager);
    }
Exemple #6
0
    public async Task AddFilesAsync(IEnumerable <FileSystemPath> files)
    {
        // Get the manager
        IArchiveDataManager manager = Archive.Manager;

        int modifiedCount = 0;

        // Add every file
        foreach (FileSystemPath file in files)
        {
            string fileName = file.Name;
            string dir      = FullPath;

            ArchiveFileViewModel?existingFile = Files.FirstOrDefault(x => x.FileName.Equals(fileName, StringComparison.OrdinalIgnoreCase));

            // Check if the file name conflicts with an existing file
            if (existingFile != null)
            {
                if (!await Services.MessageUI.DisplayMessageAsync(String.Format(Resources.Archive_AddFiles_Conflict, file), Resources.Archive_AddFiles_ConflictHeader, MessageType.Warning, true))
                {
                    continue;
                }
            }

            try
            {
                // Open the file as a stream
                using FileStream fileStream = File.OpenRead(file);

                ArchiveFileViewModel fileViewModel = existingFile ?? new ArchiveFileViewModel(new ArchiveFileItem(manager, fileName, dir, manager.GetNewFileEntry(Archive.ArchiveData ?? throw new Exception("Archive data has not been loaded"), dir, fileName)), this);

                // Replace the file with the import data
                if (await Task.Run(() => fileViewModel.ReplaceFile(fileStream)))
                {
                    modifiedCount++;
                }

                // Add the file to the list if it was created
                if (existingFile == null)
                {
                    Files.Add(fileViewModel);
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Adding files to archive directory {0}", DisplayName);

                await Services.MessageUI.DisplayExceptionMessageAsync(ex, String.Format(Resources.Archive_AddFiles_Error, file.Name));

                return;
            }
        }

        Archive.AddModifiedFiles(modifiedCount);
        Archive.ExplorerDialogViewModel.RefreshStatusBar();
    }
Exemple #7
0
    public async Task ShowArchiveCreatorAsync(IArchiveDataManager manager)
    {
        if (Application.Current.Dispatcher == null)
        {
            throw new Exception("The application does not have a valid dispatcher");
        }

        Logger.Trace("An Archive Creator window was opened");

        // Run on UI thread
        ArchiveCreatorUI ui = Application.Current.Dispatcher.Invoke(() => new ArchiveCreatorUI(new ArchiveCreatorDialogViewModel(manager)));
        await Dialog.ShowWindowAsync(ui);
    }
    /// <summary>
    /// Converts the file data to the specified format
    /// </summary>
    /// <param name="inputFormat">The format to convert from</param>
    /// <param name="outputFormat">The format to convert to</param>
    /// <param name="inputStream">The input file data stream</param>
    /// <param name="outputStream">The output stream for the converted data</param>
    /// <param name="manager">The manager</param>
    public override void ConvertTo(FileExtension inputFormat, FileExtension outputFormat, ArchiveFileStream inputStream, Stream outputStream,
                                   IArchiveDataManager manager)
    {
        // Check if it's the native format
        if (outputFormat == Format)
        {
            // Set the start position
            ReadTEXHeader(inputStream, manager);

            // Copy the image data
            inputStream.Stream.CopyTo(outputStream);
        }
        else
        {
            // Convert the image normally
            base.ConvertTo(inputFormat, outputFormat, inputStream, outputStream, manager);
        }
    }
Exemple #9
0
    /// <summary>
    /// Default constructor
    /// </summary>
    /// <param name="filePath">The file path for the archive</param>
    /// <param name="manager">The archive data manager</param>
    /// <param name="loadOperation">The operation to use when running an async operation which needs to load</param>
    /// <param name="explorerDialogViewModel">The explorer dialog view model</param>
    /// <param name="isDuplicateName">Indicates if the name of the archive matches the name of another loaded archive</param>
    public ArchiveViewModel(FileSystemPath filePath, IArchiveDataManager manager, Operation loadOperation, ArchiveExplorerDialogViewModel explorerDialogViewModel, bool isDuplicateName) : base(null, filePath.Name, null)
    {
        Logger.Info("An archive view model is being created for {0}", filePath.Name);

        // Set properties
        FilePath                = filePath;
        Manager                 = manager;
        LoadOperation           = loadOperation;
        ExplorerDialogViewModel = explorerDialogViewModel;
        IsDuplicateName         = isDuplicateName;
        ThumbnailCache          = new ArchiveThumbnailCache();

        // Create commands
        SaveCommand         = new AsyncRelayCommand(SaveAsync);
        OpenLocationCommand = new AsyncRelayCommand(OpenLocationAsync);

        // Open the file stream
        OpenFile();
    }
    /// <summary>
    /// Reads the TEX header if there is one
    /// </summary>
    /// <param name="inputStream">The input stream</param>
    /// <param name="manager">The manager</param>
    /// <returns>The TEX header, if available</returns>
    protected TextureCooked?ReadTEXHeader(ArchiveFileStream inputStream, IArchiveDataManager manager)
    {
        // Use a reader
        using Reader reader = new(inputStream.Stream, manager.Context !.GetSettings <UbiArtSettings>().GetEndian == BinarySerializer.Endian.Little, true);

        // Check if it's in a TEX wrapper
        inputStream.Stream.Position = 4;
        bool usesTexWrapper = reader.ReadUInt32() == TEXHeader;

        // Reset the position
        inputStream.Stream.Position = 0;

        // If it uses a TEX wrapper we need to serialize the header
        if (usesTexWrapper)
        {
            // Serialize the header
            return(manager.Context.ReadStreamData <TextureCooked>(inputStream.Stream, name: inputStream.Name, leaveOpen: true, onPreSerialize: x => x.Pre_SerializeImageData = false));
        }

        return(null);
    }
 /// <summary>
 /// Indicates if the specified manager supports files of this type
 /// </summary>
 /// <param name="manager">The manager to check</param>
 /// <returns>True if supported, otherwise false</returns>
 public bool IsSupported(IArchiveDataManager manager) => manager.Context?.HasSettings <OpenSpaceSettings>() is true;
Exemple #12
0
    /// <summary>
    /// Gets an image from the file data
    /// </summary>
    /// <param name="inputStream">The file data stream</param>
    /// <param name="format">The file format</param>
    /// <param name="manager">The manager to check</param>
    /// <returns>The image</returns>
    protected override MagickImage GetImage(ArchiveFileStream inputStream, FileExtension format, IArchiveDataManager manager)
    {
        // Serialize data
        TextureCooked tex = manager.Context !.ReadStreamData <TextureCooked>(inputStream.Stream, name: inputStream.Name, leaveOpen: true, onPreSerialize: x =>
        {
            x.Pre_SerializeImageData = true;
            x.Pre_FileSize           = inputStream.Stream.Length;
        });

        // Get the untiled image data
        byte[] untiledImgData = tex.Header_Xbox360.Untile(tex.ImageData, true);

        DDSParser.DDSStruct header = new()
        {
            pixelformat = new DDSParser.DDSStruct.pixelformatstruct()
            {
                rgbbitcount = 32
            },
            width  = (uint)tex.Header_Xbox360.Width,
            height = (uint)tex.Header_Xbox360.Height,
            depth  = 1
        };

        byte[] rawImgData = tex.Header_Xbox360.CompressionType switch
        {
            TextureCooked_Xbox360Header.TextureCompressionType.DXT1 => DDSParser.DecompressDXT1(header, untiledImgData),
            TextureCooked_Xbox360Header.TextureCompressionType.DXT3 => DDSParser.DecompressDXT3(header, untiledImgData),
            TextureCooked_Xbox360Header.TextureCompressionType.DXT5 => DDSParser.DecompressDXT5(header, untiledImgData),
            _ => throw new ArgumentOutOfRangeException(nameof(tex.Header_Xbox360.CompressionType), tex.Header_Xbox360.CompressionType, null)
        };

        // Return the image
        return(new MagickImage(rawImgData, new MagickReadSettings()
        {
            Format = MagickFormat.Rgba,
            Width = tex.Header_Xbox360.Width,
            Height = tex.Header_Xbox360.Height
        }));
    }
}
    /// <summary>
    /// Loads the thumbnail and display info for the file
    /// </summary>
    /// <param name="inputStream">The file data stream</param>
    /// <param name="fileExtension">The file extension</param>
    /// <param name="width">The thumbnail width</param>
    /// <param name="manager">The manager</param>
    /// <returns>The thumbnail data</returns>
    public ArchiveFileThumbnailData LoadThumbnail(ArchiveFileStream inputStream, FileExtension fileExtension, int width, IArchiveDataManager manager)
    {
        // Load the file
        GF file = GetFileContent(inputStream, manager);

        // Load the raw bitmap data
        RawBitmapData rawBmp = file.GetRawBitmapData(width, (int)(file.Height / ((double)file.Width / width)));

        var format = rawBmp.PixelFormat == PixelFormat.Format32bppArgb ? PixelFormats.Bgra32 : PixelFormats.Bgr24;

        // Get a thumbnail source
        BitmapSource thumbnailSource = BitmapSource.Create(rawBmp.Width, rawBmp.Height, 96, 96, format, null, rawBmp.PixelData, (rawBmp.Width * format.BitsPerPixel + 7) / 8);

        // Get the thumbnail with the specified size
        return(new ArchiveFileThumbnailData(thumbnailSource, new DuoGridItemViewModel[]
        {
            new DuoGridItemViewModel(
                header: new ResourceLocString(nameof(Resources.Archive_FileInfo_Img_Size)),
                text: $"{file.Width}x{file.Height}"),
            new DuoGridItemViewModel(
                header: new ResourceLocString(nameof(Resources.Archive_FileInfo_Img_HasAlpha)),
                text: new GeneratedLocString(() => $"{file.PixelFormat.SupportsTransparency()}")),
            new DuoGridItemViewModel(
                header: new ResourceLocString(nameof(Resources.Archive_FileInfo_Img_Mipmaps)),
                text: $"{file.ExclusiveMipmapCount}"),
            new DuoGridItemViewModel(
                header: new ResourceLocString(nameof(Resources.Archive_FileInfo_Format)),
                text: $"{file.PixelFormat.ToString().Replace("Format_", "")}",
                minUserLevel: UserLevel.Technical),
        }));
    }
Exemple #14
0
    /// <summary>
    /// Default constructor
    /// </summary>
    /// <param name="manager">The archive data manager</param>
    /// <param name="filePaths">The archive file paths</param>
    public ArchiveExplorerDialogViewModel(IArchiveDataManager manager, FileSystemPath[] filePaths)
    {
        // Create commands
        NavigateToAddressCommand = new RelayCommand(() => LoadDirectory(CurrentDirectoryAddress));
        DeleteSelectedDirCommand = new AsyncRelayCommand(DeleteSelectedDirAsync);

        // Set properties
        CurrentDirectorySuggestions = new ObservableCollection <string>();
        StatusBarItems = new ObservableCollection <LocalizedString>();
        SearchProvider = new BaseSuggestionProvider(SearchForEntries);

        BindingOperations.EnableCollectionSynchronization(StatusBarItems, Application.Current);

        // TODO: Do not load the archives in the constructor! Create a separate init method or similar.

        try
        {
            // Set the default title
            Title = Resources.Archive_Title;

            // Get the manager
            Manager = manager;

            // Create the load action
            Operation load = new(() => IsLoading = true, () => IsLoading = false);

            // Get the archives
            Archives = filePaths.Select(x => new ArchiveViewModel(x, manager, load, this, filePaths.Any(f => f != x && f.Name == x.Name))).ToArray();

            // Set the archive lock
            ArchiveLock = new AsyncLock();

            Logger.Info("The Archive Explorer is loading with {0} archives", Archives.Length);

            // Make sure we got an archive
            if (!Archives.Any())
            {
                throw new ArgumentException("At least one archive path needs to be available");
            }

            // Lock when accessing the archive
            using (ArchiveLock.Lock())
            {
                // Load each archive
                foreach (var archive in Archives)
                {
                    archive.LoadArchive();
                }
            }

            // Select and expand the first item
            Archives.First().IsSelected = true;
            Archives.First().IsExpanded = true;
        }
        catch
        {
            // Make sure the view model gets disposed
            Dispose();

            throw;
        }
    }
Exemple #15
0
 /// <summary>
 /// Converts the file data from the specified format
 /// </summary>
 /// <param name="inputFormat">The format to convert from</param>
 /// <param name="outputFormat">The format to convert to</param>
 /// <param name="currentFileStream">The current file stream</param>
 /// <param name="inputStream">The input file data stream to convert from</param>
 /// <param name="outputStream">The output stream for the converted data</param>
 /// <param name="manager">The manager</param>
 public virtual void ConvertFrom(FileExtension inputFormat, FileExtension outputFormat, ArchiveFileStream currentFileStream, ArchiveFileStream inputStream, ArchiveFileStream outputStream, IArchiveDataManager manager)
 {
     throw new NotSupportedException("Converting .wav files is not supported");
 }
    /// <summary>
    /// Gets an image from the file data
    /// </summary>
    /// <param name="inputStream">The file data stream</param>
    /// <param name="format">The file format</param>
    /// <param name="manager">The manager to check</param>
    /// <returns>The image</returns>
    protected override MagickImage GetImage(ArchiveFileStream inputStream, FileExtension format, IArchiveDataManager manager)
    {
        // Set the Stream position
        ReadTEXHeader(inputStream, manager);

        // Return the image
        return(new MagickImage(inputStream.Stream));
    }
    /// <summary>
    /// Loads the thumbnail and display info for the file
    /// </summary>
    /// <param name="inputStream">The file data stream</param>
    /// <param name="fileExtension">The file extension</param>
    /// <param name="width">The thumbnail width</param>
    /// <param name="manager">The manager</param>
    /// <returns>The thumbnail data</returns>
    public virtual ArchiveFileThumbnailData LoadThumbnail(ArchiveFileStream inputStream, FileExtension fileExtension, int width, IArchiveDataManager manager)
    {
        // Get the image
        using MagickImage img = GetImage(inputStream, fileExtension, manager);

        // Resize to a thumbnail
        img.Thumbnail(width, (int)(img.Height / ((double)img.Width / width)));

        BitmapSource thumb = img.ToBitmapSource();

        return(new ArchiveFileThumbnailData(thumb, new DuoGridItemViewModel[]
        {
            new DuoGridItemViewModel(
                header: new ResourceLocString(nameof(Resources.Archive_FileInfo_Img_Size)),
                text: $"{img.Width}x{img.Height}"),
            new DuoGridItemViewModel(
                header: new ResourceLocString(nameof(Resources.Archive_FileInfo_Format)),
                text: new GeneratedLocString(() => $"{GetFormat(fileExtension)}")),
        }));
    }
 /// <summary>
 /// Indicates if the specified manager supports files of this type
 /// </summary>
 /// <param name="manager">The manager to check</param>
 /// <returns>True if supported, otherwise false</returns>
 public virtual bool IsSupported(IArchiveDataManager manager) => true;
 /// <summary>
 /// Converts the file data from the specified format
 /// </summary>
 /// <param name="inputFormat">The format to convert from</param>
 /// <param name="outputFormat">The format to convert to</param>
 /// <param name="currentFileStream">The current file stream</param>
 /// <param name="inputStream">The input file data stream to convert from</param>
 /// <param name="outputStream">The output stream for the converted data</param>
 /// <param name="manager">The manager</param>
 public virtual void ConvertFrom(FileExtension inputFormat, FileExtension outputFormat, ArchiveFileStream currentFileStream, ArchiveFileStream inputStream, ArchiveFileStream outputStream, IArchiveDataManager manager)
 {
     ConvertFrom(inputFormat, GetMagickFormat(outputFormat), inputStream, outputStream);
 }
Exemple #20
0
    /// <summary>
    /// Exports the directory
    /// </summary>
    /// <param name="forceNativeFormat">Indicates if the native format should be forced</param>
    /// <param name="selectedFilesOnly">Indicates if only selected files in the current directory should be exported</param>
    /// <returns>The task</returns>
    public async Task ExportAsync(bool forceNativeFormat, bool selectedFilesOnly = false)
    {
        // Run as a load operation
        using (await Archive.LoadOperation.RunAsync())
        {
            // Lock the access to the archive
            using (await Archive.ArchiveLock.LockAsync())
            {
                // Get the output path
                DirectoryBrowserResult result = await Services.BrowseUI.BrowseDirectoryAsync(new DirectoryBrowserViewModel()
                {
                    Title = Resources.Archive_ExportHeader
                });

                if (result.CanceledByUser)
                {
                    return;
                }

                // Make sure there isn't an existing file at the output path
                if ((result.SelectedDirectory + ExportDirName).FileExists)
                {
                    await Services.MessageUI.DisplayMessageAsync(String.Format(Resources.Archive_ExportDirFileConflict, ExportDirName), MessageType.Error);

                    return;
                }

                // Run as a task
                await Task.Run(async() =>
                {
                    // Get the manager
                    IArchiveDataManager manager = Archive.Manager;

                    // Save the selected format for each collection
                    Dictionary <IArchiveFileType, FileExtension?> selectedFormats = new();

                    try
                    {
                        ArchiveDirectoryViewModel[] allDirs;

                        if (selectedFilesOnly)
                        {
                            allDirs = new ArchiveDirectoryViewModel[]
                            {
                                this
                            }
                        }
                        ;
                        else
                        {
                            allDirs = this.GetAllChildren(true).ToArray();
                        }

                        int fileIndex  = 0;
                        int filesCount = allDirs.SelectMany(x => x.Files).Count(x => !selectedFilesOnly || x.IsSelected);

                        // Handle each directory
                        foreach (ArchiveDirectoryViewModel item in allDirs)
                        {
                            // Get the directory path
                            FileSystemPath path = result.SelectedDirectory + ExportDirName + item.FullPath.Remove(0, FullPath.Length).Trim(manager.PathSeparatorCharacter);

                            // Create the directory
                            Directory.CreateDirectory(path);

                            // Save each file
                            foreach (ArchiveFileViewModel file in item.Files.Where(x => !selectedFilesOnly || x.IsSelected))
                            {
                                // Get the file stream
                                using ArchiveFileStream fileStream = file.GetDecodedFileStream();

                                // Initialize the file without loading the thumbnail
                                file.InitializeFile(fileStream, ArchiveFileViewModel.ThumbnailLoadMode.None);

                                fileStream.SeekToBeginning();

                                // Check if the format has not been selected
                                if (!forceNativeFormat && !selectedFormats.ContainsKey(file.FileType) && file.FileType is not ArchiveFileType_Default)
                                {
                                    // Get the available extensions
                                    string[] ext = new string[]
                                    {
                                        Resources.Archive_Export_Format_Original
                                    }.Concat(file.FileType.ExportFormats.Select(x => x.FileExtensions)).ToArray();

                                    // Have user select the format
                                    FileExtensionSelectionDialogResult extResult = await Services.UI.SelectFileExtensionAsync(new FileExtensionSelectionDialogViewModel(ext, String.Format(Resources.Archive_FileExtensionSelectionInfoHeader, file.FileType.TypeDisplayName)));

                                    // Since this operation can't be canceled we get the first format
                                    if (extResult.CanceledByUser)
                                    {
                                        extResult.SelectedFileFormat = ext.First();
                                    }

                                    // Add the selected format
                                    FileExtension?e = extResult.SelectedFileFormat == ext.First()
                                        ? null
                                        : new FileExtension(extResult.SelectedFileFormat, multiple: true);

                                    selectedFormats.Add(file.FileType, e);
                                }

                                // Get the selected format
                                FileExtension?format = forceNativeFormat || file.FileType is ArchiveFileType_Default
                                    ? null
                                    : selectedFormats[file.FileType];

                                // Get the final file name to use when exporting
                                FileSystemPath exportFileName = format == null
                                    ? new FileSystemPath(file.FileName)
                                    : new FileSystemPath(file.FileName).ChangeFileExtension(format, true);

                                Archive.SetDisplayStatus($"{String.Format(Resources.Archive_ExportingFileStatus, file.FileName)}" +
                                                         $"{Environment.NewLine}{++fileIndex}/{filesCount}");

                                try
                                {
                                    // Export the file
                                    file.ExportFile(path + exportFileName, fileStream, format);
                                }
                                catch (Exception ex)
                                {
                                    // If the export failed for a native format we throw
                                    if (format == null)
                                    {
                                        throw;
                                    }

                                    Logger.Error(ex, "Exporting archive file {0}", file.FileName);

                                    // If the export failed and we tried converting it we instead export it as the native format
                                    // Start by setting the file in the error state, thus changing the type
                                    file.InitializeAsError();

                                    // Seek to the beginning of the stream in case some bytes were read
                                    fileStream.SeekToBeginning();

                                    // Export the file as the native format
                                    file.ExportFile(path + file.FileName, fileStream, null);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex, "Exporting archive directory {0}", DisplayName);

                        await Services.MessageUI.DisplayExceptionMessageAsync(ex, String.Format(Resources.Archive_ExportError, DisplayName));

                        return;
                    }
                    finally
                    {
                        Archive.SetDisplayStatus(String.Empty);
                    }

                    await Services.MessageUI.DisplaySuccessfulActionMessageAsync(Resources.Archive_ExportFilesSuccess);
                });
            }
        }
    }
Exemple #21
0
    public Page_Games_GameViewModel GetDisplayViewModel()
    {
        try
        {
            if (IsAdded)
            {
                var actions = new List <OverflowButtonItemViewModel>();

                // Get the manager
                var manager = Game.GetManager(Game.GetGameType());

                // Add launch options if set to do so
                if (Game.GetLaunchMode() == UserData_GameLaunchMode.AsAdminOption)
                {
                    actions.Add(new OverflowButtonItemViewModel(Resources.GameDisplay_RunAsAdmin, GenericIconKind.GameDisplay_Admin, new AsyncRelayCommand(async() => await Game.GetManager().LaunchGameAsync(true))));

                    actions.Add(new OverflowButtonItemViewModel());
                }

                // Get the Game links
                var links = GetGameFileLinks?.Where(x => x.Path.FileExists).ToArray();

                // Add links if there are any
                if (links?.Any() ?? false)
                {
                    actions.AddRange(links.
                                     Select(x =>
                    {
                        // Get the path
                        string path = x.Path;

                        // Create the command
                        var command = new AsyncRelayCommand(async() => (await Services.File.LaunchFileAsync(path, arguments: x.Arguments))?.Dispose());

                        if (x.Icon != GenericIconKind.None)
                        {
                            return(new OverflowButtonItemViewModel(x.Header, x.Icon, command));
                        }

                        try
                        {
                            return(new OverflowButtonItemViewModel(x.Header, WindowsHelpers.GetIconOrThumbnail(x.Path, ShellThumbnailSize.Small).ToImageSource(), command));
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex, "Getting file icon for overflow button item");
                            return(new OverflowButtonItemViewModel(x.Header, x.Icon, command));
                        }
                    }));

                    actions.Add(new OverflowButtonItemViewModel());
                }

                // Get additional items
                var additionalItems = manager.GetAdditionalOverflowButtonItems;

                // Add the items if there are any
                if (additionalItems.Any())
                {
                    actions.AddRange(additionalItems);

                    actions.Add(new OverflowButtonItemViewModel());
                }

                // Add RayMap link
                if (RayMapURL != null)
                {
                    actions.Add(new OverflowButtonItemViewModel(Resources.GameDisplay_Raymap, GenericIconKind.GameDisplay_Map, new AsyncRelayCommand(async() => (await Services.File.LaunchFileAsync(RayMapURL))?.Dispose())));
                    actions.Add(new OverflowButtonItemViewModel());
                }

                // Add open archive
                if (HasArchives)
                {
                    actions.Add(new OverflowButtonItemViewModel(Resources.GameDisplay_Archives, GenericIconKind.GameDisplay_Archive, new AsyncRelayCommand(async() =>
                    {
                        using IArchiveDataManager archiveDataManager = GetArchiveDataManager;

                        try
                        {
                            // Show the archive explorer
                            await Services.UI.ShowArchiveExplorerAsync(archiveDataManager, GetArchiveFilePaths(Game.GetInstallDir()).Where(x => x.FileExists).ToArray());
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex, "Archive explorer");

                            await Services.MessageUI.DisplayExceptionMessageAsync(ex, Resources.Archive_CriticalError);
                        }
                    }), UserLevel.Advanced));
                }

                // Add open location
                actions.Add(new OverflowButtonItemViewModel(Resources.GameDisplay_OpenLocation, GenericIconKind.GameDisplay_Location, new AsyncRelayCommand(async() =>
                {
                    // Get the install directory
                    var instDir = Game.GetInstallDir();

                    // Select the file in Explorer if it exists
                    if ((instDir + DefaultFileName).FileExists)
                    {
                        instDir += DefaultFileName;
                    }

                    // Open the location
                    await Services.File.OpenExplorerLocationAsync(instDir);

                    Logger.Trace("The Game {0} install location was opened", Game);
                }), UserLevel.Advanced));

                actions.Add(new OverflowButtonItemViewModel(UserLevel.Advanced));

                // Add Game options
                var optionsAction = new OverflowButtonItemViewModel(Resources.GameDisplay_Options, GenericIconKind.GameDisplay_Config, new AsyncRelayCommand(async() =>
                {
                    Logger.Trace("The Game {0} options dialog is opening...", Game);
                    await GameOptionsDialog.ShowAsync(Game);
                }));

                actions.Add(optionsAction);

                return(new Page_Games_GameViewModel(
                           game: Game,
                           displayName: DisplayName,
                           iconSource: IconSource,
                           isDemo: IsDemo,
                           mainAction: new ActionItemViewModel(Resources.GameDisplay_Launch, GenericIconKind.GameDisplay_Play, new AsyncRelayCommand(async() => await Game.GetManager().LaunchGameAsync(false))),
                           secondaryAction: optionsAction,
                           launchActions: actions));
            }
            else
            {
                var actions = new List <OverflowButtonItemViewModel>();

                OverflowButtonItemViewModel downloadItem = null;

                if (CanBeDownloaded)
                {
                    downloadItem = new OverflowButtonItemViewModel(Resources.GameDisplay_CloudInstall, GenericIconKind.GameDisplay_Download, new AsyncRelayCommand(async() => await DownloadGameAsync()));

                    if (CanBeLocated)
                    {
                        actions.Add(downloadItem);
                        actions.Add(new OverflowButtonItemViewModel());
                    }
                }

                // Get the purchase links
                var links = Game.
                            // Get all available managers
                            GetManagers().
                            // Get the purchase links
                            SelectMany(x => x.GetGamePurchaseLinks);

                // Add links
                actions.AddRange(links.
                                 Select(x =>
                {
                    // Get the path
                    string path = x.Path;

                    // Create the command
                    var command = new AsyncRelayCommand(async() => (await Services.File.LaunchFileAsync(path))?.Dispose());

                    // Return the item
                    return(new OverflowButtonItemViewModel(x.Header, x.Icon, command));
                }));

                // Add disc installer options for specific Games
                if (CanBeInstalledFromDisc)
                {
                    // Add separator if there are previous actions
                    if (actions.Any())
                    {
                        actions.Add(new OverflowButtonItemViewModel());
                    }

                    // Add disc installer action
                    actions.Add(new OverflowButtonItemViewModel(Resources.GameDisplay_DiscInstall, GenericIconKind.GameDisplay_DiscInstall, new AsyncRelayCommand(async() =>
                    {
                        // Show and run the installer
                        await Services.DialogBaseManager.ShowDialogWindowAsync(new GameInstaller_Window(Game));
                    })));
                }

                // If the last option is a separator, remove it
                if (actions.LastOrDefault()?.IsSeparator == true)
                {
                    actions.RemoveAt(actions.Count - 1);
                }

                // Create the main action
                var mainAction = CanBeLocated
                    ? new ActionItemViewModel(Resources.GameDisplay_Locate, GenericIconKind.GameDisplay_Location, new AsyncRelayCommand(async() => await LocateGameAsync()))
                    : downloadItem;

                // Return the view model
                return(new Page_Games_GameViewModel(Game, DisplayName, IconSource, IsDemo, mainAction, null, actions));
            }
        }
        catch (Exception ex)
        {
            Logger.Fatal(ex, "Getting game display view model");
            throw;
        }
    }
 public virtual bool IsOfType(ArchiveFileStream inputStream, IArchiveDataManager manager, TextureCooked?tex) => false;
    /// <summary>
    /// Indicates if a file with the specifies file extension and data is of this type
    /// </summary>
    /// <param name="fileExtension">The file extension to check</param>
    /// <param name="inputStream">The file data to check</param>
    /// <param name="manager">The manager</param>
    /// <returns>True if it is of this type, otherwise false</returns>
    public override bool IsOfType(FileExtension fileExtension, ArchiveFileStream inputStream, IArchiveDataManager manager)
    {
        if (fileExtension != new FileExtension(".tga.ckd", multiple: true) && fileExtension != new FileExtension(".png.ckd", multiple: true))
        {
            return(false);
        }

        // Set the Stream position
        TextureCooked?tex = ReadTEXHeader(inputStream, manager);

        // Check for type match
        if (IsOfType(inputStream, manager, tex))
        {
            return(true);
        }

        // If the format has a magic header we check for it
        if (FormatMagic != null)
        {
            // Use a reader
            using Reader reader = new(inputStream.Stream, manager.Context !.GetSettings <UbiArtSettings>().GetEndian == BinarySerializer.Endian.Little, true);

            // Get the magic header
            uint magic = reader.ReadUInt32();

            // Check if it matches the magic
            return(magic == FormatMagic);
        }

        return(false);
    }
 /// <summary>
 /// Indicates if the specified manager supports files of this type
 /// </summary>
 /// <param name="manager">The manager to check</param>
 /// <returns>True if supported, otherwise false</returns>
 public override bool IsSupported(IArchiveDataManager manager) => manager.Context?.HasSettings <UbiArtSettings>() is true;
 /// <summary>
 /// Gets an image from the file data
 /// </summary>
 /// <param name="inputStream">The file data stream</param>
 /// <param name="format">The file format</param>
 /// <param name="manager">The manager to check</param>
 /// <returns>The image</returns>
 protected virtual MagickImage GetImage(ArchiveFileStream inputStream, FileExtension format, IArchiveDataManager manager) => new MagickImage(inputStream.Stream, GetMagickFormat(format));
 /// <summary>
 /// Loads the thumbnail and display info for the file
 /// </summary>
 /// <param name="inputStream">The file data stream</param>
 /// <param name="fileExtension">The file extension</param>
 /// <param name="width">The thumbnail width</param>
 /// <param name="manager">The manager</param>
 /// <returns>The thumbnail data</returns>
 public override ArchiveFileThumbnailData LoadThumbnail(ArchiveFileStream inputStream, FileExtension fileExtension, int width, IArchiveDataManager manager)
 {
     // Only load thumbnails for supported formats
     if (!IsFormatSupported)
     {
         return(new ArchiveFileThumbnailData(null, Array.Empty <DuoGridItemViewModel>()));
     }
     else
     {
         return(base.LoadThumbnail(inputStream, fileExtension, width, manager));
     }
 }
 /// <summary>
 /// Indicates if a file with the specifies file extension and data is of this type
 /// </summary>
 /// <param name="fileExtension">The file extension to check</param>
 /// <param name="inputStream">The file data to check</param>
 /// <param name="manager">The manager</param>
 /// <returns>True if it is of this type, otherwise false</returns>
 public virtual bool IsOfType(FileExtension fileExtension, ArchiveFileStream inputStream, IArchiveDataManager manager) => false;
Exemple #28
0
 /// <summary>
 /// Loads the thumbnail and display info for the file
 /// </summary>
 /// <param name="inputStream">The file data stream</param>
 /// <param name="fileExtension">The file extension</param>
 /// <param name="width">The thumbnail width</param>
 /// <param name="manager">The manager</param>
 /// <returns>The thumbnail data</returns>
 public virtual ArchiveFileThumbnailData LoadThumbnail(ArchiveFileStream inputStream, FileExtension fileExtension, int width, IArchiveDataManager manager)
 {
     return(new ArchiveFileThumbnailData(null, new DuoGridItemViewModel[]
     {
         // TODO: Read and include .wav metadata, such as track length etc.
     }));
 }
    /// <summary>
    /// Converts the file data to the specified format
    /// </summary>
    /// <param name="inputFormat">The format to convert from</param>
    /// <param name="outputFormat">The format to convert to</param>
    /// <param name="inputStream">The input file data stream</param>
    /// <param name="outputStream">The output stream for the converted data</param>
    /// <param name="manager">The manager</param>
    public virtual void ConvertTo(FileExtension inputFormat, FileExtension outputFormat, ArchiveFileStream inputStream, Stream outputStream, IArchiveDataManager manager)
    {
        // Get the image
        using MagickImage img = GetImage(inputStream, inputFormat, manager);

        // Write to stream as new format
        img.Write(outputStream, GetMagickFormat(outputFormat.FileExtensions));
    }
    /// <summary>
    /// Converts the file data from the specified format
    /// </summary>
    /// <param name="inputFormat">The format to convert from</param>
    /// <param name="outputFormat">The format to convert to</param>
    /// <param name="currentFileStream">The current file stream</param>
    /// <param name="inputStream">The input file data stream to convert from</param>
    /// <param name="outputStream">The output stream for the converted data</param>
    /// <param name="manager">The manager</param>
    public override void ConvertFrom(FileExtension inputFormat, FileExtension outputFormat, ArchiveFileStream currentFileStream,
                                     ArchiveFileStream inputStream, ArchiveFileStream outputStream, IArchiveDataManager manager)
    {
        // Get the current TEX data
        TextureCooked?tex = ReadTEXHeader(currentFileStream, manager);

        // If there's no TEX header we handle the image data directly
        if (tex == null)
        {
            if (outputFormat == Format)
            {
                inputStream.Stream.CopyTo(outputStream.Stream);
            }
            else
            {
                ConvertFrom(inputFormat, MagickFormat, inputStream, outputStream);
            }
        }
        else
        {
            // Get the image in specified format
            using MagickImage img = new(inputStream.Stream, GetMagickFormat(inputFormat.FileExtensions));

            // Change the type to the output format
            img.Format = MagickFormat;

            // Get the image bytes
            byte[] bytes = img.ToByteArray();

            // Update the TEX header
            tex.Height = (ushort)img.Height;
            tex.Width  = (ushort)img.Width;
            // TODO: Figure out what the values are on Wii U where they don't match the actual size
            tex.TextureSize  = (uint)bytes.Length;
            tex.TextureSize2 = (uint)bytes.Length;
            tex.ImageData    = bytes;

            tex.Pre_SerializeImageData = true;

            // Write the TEX file
            manager.Context !.WriteStreamData(outputStream.Stream, tex, name: outputStream.Name, leaveOpen: true);
        }
    }