From 691b0667bc7b5857596cd984dfd961d61fc577de Mon Sep 17 00:00:00 2001 From: Yoshi Askharoun Date: Tue, 26 Oct 2021 14:48:45 -0500 Subject: [PATCH] Added Background Image Mod --- ZuneModCore/Mod.cs | 1 + ZuneModCore/Mods/BackgroundImageMod.cs | 133 +++++++++++++++++++++++++ ZuneModCore/ZuneModCore.csproj | 1 + 3 files changed, 135 insertions(+) create mode 100644 ZuneModCore/Mods/BackgroundImageMod.cs diff --git a/ZuneModCore/Mod.cs b/ZuneModCore/Mod.cs index 845279c..3cd97e7 100644 --- a/ZuneModCore/Mod.cs +++ b/ZuneModCore/Mod.cs @@ -17,6 +17,7 @@ namespace ZuneModCore new FeaturesOverrideMod(), new VideoSyncMod(), new WebservicesMod(), + new BackgroundImageMod(), new MbidLocatorMod(), }.AsReadOnly(); diff --git a/ZuneModCore/Mods/BackgroundImageMod.cs b/ZuneModCore/Mods/BackgroundImageMod.cs new file mode 100644 index 0000000..217c49e --- /dev/null +++ b/ZuneModCore/Mods/BackgroundImageMod.cs @@ -0,0 +1,133 @@ +using OwlCore.AbstractUI.Models; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Threading.Tasks; +using Vestris.ResourceLib; +using ZuneModCore.Win32; + +namespace ZuneModCore.Mods +{ + public class BackgroundImageMod : Mod + { + public override string Id => nameof(BackgroundImageMod); + + public override string Title => "Background Image"; + + public override string Description => "Replaces the \"Zero\" background with an image of your choice."; + + public override string Author => "Joshua \"Yoshi\" Askharoun"; + + public override AbstractUIElementGroup? GetDefaultOptionsUI() + { + return new(nameof(BackgroundImageMod)) + { + Title = "Select background image:", + Items = + { + new AbstractTextBox("fileBox", Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)), + } + }; + } + + public override IReadOnlyList? DependentMods => null; + + public override async Task Apply() + { + string bgimgPath = ((AbstractTextBox)OptionsUI!.Items[0]).Value; + FileInfo bgimgInfo = new(bgimgPath); + if (!bgimgInfo.Exists) + { + return $"The file '{bgimgInfo.FullName}' does not exist."; + } + + FileInfo zsrDllInfo = new(Path.Combine(ZuneInstallDir, "ZuneShellResources.dll")); + if (!zsrDllInfo.Exists) + { + return $"The file '{zsrDllInfo.FullName}' does not exist."; + } + + // Make a backup if it doesn't already exist + FileInfo zsrDllBackupInfo = new(Path.Combine(StorageDirectory, "ZuneShellResources.original.dll")); + if (!zsrDllBackupInfo.Exists) + { + File.Copy(zsrDllInfo.FullName, zsrDllBackupInfo.FullName, true); + } + + string zsrDllTempPath = Path.Combine(StorageDirectory, zsrDllInfo.Name); + + // Take ownership of DLL + TokenManipulator.TakeOwnership(zsrDllInfo); + + try + { + using (ResourceInfo vi = new()) + { + // Load the RCDATA section + vi.Load(zsrDllInfo.FullName); + ResourceId? resId = vi.ResourceTypes.Find(id => + { + // This must be wrapped in a try-catch block, + // otherwise resourcelib will error when attempting + // to read the WAVE type (or any other non-default type). + try + { + return id.ResourceType == Kernel32.ResourceTypes.RT_RCDATA; + } + catch + { + return false; + } + }); + if (resId == null) + return $"Failed to locate image resources in Zune software."; + + // Locate the image resource + List RCDATA = vi.Resources[resId]; + int idx = RCDATA.FindIndex(r => r.Name.Name == "FRAMEBACKGROUND06.PNG"); + if (idx < 0) + return $"Failed to locate background image resource in Zune software."; + GenericResource ogRes = (GenericResource)RCDATA[idx]; + + // Replace image + byte[] data = await File.ReadAllBytesAsync(bgimgInfo.FullName); + BitmapResource newRes = new(IntPtr.Zero, IntPtr.Zero, resId, ogRes.Name, ogRes.Language, data.Length); + newRes.Bitmap = new(data); + RCDATA[idx] = newRes; + File.Copy(zsrDllInfo.FullName, zsrDllTempPath, true); + newRes.SaveTo(zsrDllTempPath); + } + File.Copy(zsrDllTempPath, zsrDllInfo.FullName, true); + + return null; + } + catch (IOException) + { + return $"Unable to replace '{zsrDllInfo.FullName}'. Verify that the Zune software is not running and try again."; + } + catch (Exception ex) + { + Debug.WriteLine(ex.ToString()); + return ex.Message; + } + } + + public override Task Reset() + { + try + { + // Copy backup to application folder + File.Copy(Path.Combine(StorageDirectory, "ZuneShellResources.original.dll"), + Path.Combine(ZuneInstallDir, "ZuneShellResources.dll"), true); + + return Task.FromResult(null); + } + catch (Exception ex) + { + return Task.FromResult(ex.Message)!; + } + } + } +} diff --git a/ZuneModCore/ZuneModCore.csproj b/ZuneModCore/ZuneModCore.csproj index bd600dc..9a709d5 100644 --- a/ZuneModCore/ZuneModCore.csproj +++ b/ZuneModCore/ZuneModCore.csproj @@ -12,6 +12,7 @@ +