public ArchiveFileItem(IArchiveDataManager manager, string fileName, string directory, object archiveEntry) { Manager = manager; FileName = fileName; Directory = directory; ArchiveEntry = archiveEntry; }
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); }
/// <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; }
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); } }
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); }
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(); }
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); } }
/// <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;
/// <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), })); }
/// <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; } }
/// <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); }
/// <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); }); } } }
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;
/// <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); } }