Improved mod interface; Basic mod install process

This commit is contained in:
Joshua Askharoun
2021-04-26 04:28:43 -05:00
parent c8cf308cc3
commit 7161797d74
6 changed files with 141 additions and 87 deletions
+18 -4
View File
@@ -29,15 +29,29 @@ namespace ZuneModCore
public virtual Task Init() => Task.CompletedTask;
public abstract Task<bool> Apply();
public abstract Task<string?> Apply();
public abstract Task<bool> Reset();
public abstract Task<string?> Reset();
public abstract AbstractUIElementGroup? OptionsUI { get; }
public string StorageDirectory => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"ZuneModCore", Id);
public string StorageDirectory
{
get
{
string dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ZuneModCore", Id);
// Create the directory just in case the consumer assumes the folder exists already
Directory.CreateDirectory(dir);
return dir;
}
}
public abstract IReadOnlyList<Type>? DependentMods { get; }
internal FileStream OpenFileInStorageDirectory(string filename)
{
FileInfo info = new(Path.Combine(StorageDirectory, filename));
return File.Create(info.FullName);
}
}
}
+4 -4
View File
@@ -61,23 +61,23 @@ namespace ZuneModCore.Mods
return Task.CompletedTask;
}
public override Task<bool> Apply()
public override Task<string?> Apply()
{
// TODO: Use user choices from AbstractUI
foreach (AbstractUIElement uiElem in OptionsUI.Items)
if (uiElem is AbstractBooleanUIElement boolElem)// && boolElem.State)
SetFeatureOverride(boolElem.Id, true);
return Task.FromResult(true);
return Task.FromResult<string?>(null);
}
public override Task<bool> Reset()
public override Task<string?> Reset()
{
foreach (AbstractUIElement uiElem in OptionsUI.Items)
if (uiElem is AbstractBooleanUIElement boolElem)
ResetFeatureOverride(boolElem.Id);
return Task.FromResult(true);
return Task.FromResult<string?>(null);
}
public static void SetFeatureOverride(string feature, bool value) =>
+7 -26
View File
@@ -8,16 +8,6 @@ namespace ZuneModCore.Mods
{
public class VideoSyncMod : Mod
{
public VideoSyncMod()
{
testButton.Clicked += TestButton_Clicked;
}
private void TestButton_Clicked(object? sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Howdy, Zune! How are ya?");
}
public override string Title => "Fix Video Sync";
public override string Description =>
@@ -25,30 +15,21 @@ namespace ZuneModCore.Mods
public override string Id => nameof(VideoSyncMod);
public override AbstractUIElementGroup OptionsUI => new(nameof(VideoSyncMod))
{
Title = Title,
Items =
{
new AbstractBooleanUIElement("test", "Is this is test?"),
testButton
}
};
public override AbstractUIElementGroup? OptionsUI => null;
private readonly AbstractButton testButton = new(nameof(testButton), "Howdy Zune!", type: AbstractButtonType.Generic);
public override Task<bool> Apply()
public override Task<string?> Apply()
{
var writer = File.CreateText(Path.Combine(StorageDirectory, "1.log"));
var writer = new StreamWriter(OpenFileInStorageDirectory("1.log"));
writer.WriteLine("Hello world");
writer.Flush();
writer.Close();
return Task.FromResult(true);
return Task.FromResult<string?>(null);
}
public override Task<bool> Reset()
public override Task<string?> Reset()
{
return Task.FromResult(true);
return Task.FromResult<string?>(null);
}
public override IReadOnlyList<Type>? DependentMods => null;
+54 -36
View File
@@ -5,10 +5,6 @@ using System.IO;
using System.Threading.Tasks;
using static ZuneModCore.Mods.FeaturesOverrideMod;
#if DEBUG
using System.Diagnostics;
#endif
namespace ZuneModCore.Mods
{
public class WebservicesMod : Mod
@@ -31,48 +27,70 @@ namespace ZuneModCore.Mods
public override IReadOnlyList<Type>? DependentMods => null;
public override Task<bool> Apply()
public override Task<string?> Apply()
{
// Open ZuneServices.dll
// Verify that ZuneServices.dll exists
FileInfo zsDllInfo = new(Path.Combine(ZuneInstallDir, "ZuneService.dll"));
if (!zsDllInfo.Exists)
return Task.FromResult(true);
using FileStream zsDll = zsDllInfo.Open(FileMode.Open);
using BinaryWriter zsDllWriter = new(zsDll);
using BinaryReader zsDllReader = new(zsDll);
{
return Task.FromResult<string?>($"The file '{zsDllInfo.FullName}' does not exist.");
}
// Verify that the DLL is from v4.8 (other versions not tested)
zsDllReader.BaseStream.Position = 0x12C824;
var versionBytes = zsDllReader.ReadBytes(ZUNE_4_8_VERSION_BYTES.Length * 2);
if (versionBytes[0] != '4' || versionBytes[2] != '.' || versionBytes[4] != '8')
return Task.FromResult(true);
// Make a backup of the file
File.Copy(zsDllInfo.FullName, Path.Combine(StorageDirectory, "ZuneService.original.dll"));
// Patch ZuneServices.dll to use zunes.tk instead of zune.net
zsDllReader.BaseStream.Position = ZUNESERVICES_ENDPOINTS_BLOCK_OFFSET;
string endpointBlock = System.Text.Encoding.Unicode.GetString(zsDllReader.ReadBytes(ZUNESERVICES_ENDPOINTS_BLOCK_LENGTH));
endpointBlock = endpointBlock.Replace("zune.net", "zunes.tk");
byte[] endpointBytes = System.Text.Encoding.Unicode.GetBytes(endpointBlock);
if (endpointBytes.Length != ZUNESERVICES_ENDPOINTS_BLOCK_LENGTH)
return Task.FromResult(false);
zsDllWriter.Seek(ZUNESERVICES_ENDPOINTS_BLOCK_OFFSET, SeekOrigin.Begin);
zsDllWriter.Write(endpointBytes);
try
{
// Open the file
using FileStream zsDll = zsDllInfo.Open(FileMode.Open);
using BinaryWriter zsDllWriter = new(zsDll);
using BinaryReader zsDllReader = new(zsDll);
// Verify that the DLL is from v4.8 (other versions not tested)
zsDllReader.BaseStream.Position = 0x12C824;
var versionBytes = zsDllReader.ReadBytes(ZUNE_4_8_VERSION_BYTES.Length * 2);
if (versionBytes[0] != '4' || versionBytes[2] != '.' || versionBytes[4] != '8')
{
return Task.FromResult<string?>("This mod has not been tested on versions earlier than 4.8.");
}
// Patch ZuneServices.dll to use zunes.tk instead of zune.net
zsDllReader.BaseStream.Position = ZUNESERVICES_ENDPOINTS_BLOCK_OFFSET;
string endpointBlock = System.Text.Encoding.Unicode.GetString(zsDllReader.ReadBytes(ZUNESERVICES_ENDPOINTS_BLOCK_LENGTH));
endpointBlock = endpointBlock.Replace("zune.net", "zunes.tk");
byte[] endpointBytes = System.Text.Encoding.Unicode.GetBytes(endpointBlock);
if (endpointBytes.Length != ZUNESERVICES_ENDPOINTS_BLOCK_LENGTH)
{
return Task.FromResult<string?>("Failed to safely overwrite strings in DLL.");
}
zsDllWriter.Seek(ZUNESERVICES_ENDPOINTS_BLOCK_OFFSET, SeekOrigin.Begin);
zsDllWriter.Write(endpointBytes);
// Enable all feature overrides affected by new servers
SetFeatureOverride("Apps", true);
SetFeatureOverride("Channels", true);
SetFeatureOverride("Games", true);
SetFeatureOverride("Marketplace", true);
SetFeatureOverride("Music", true);
SetFeatureOverride("MusicVideos", true);
SetFeatureOverride("Podcasts", true);
SetFeatureOverride("Social", true);
SetFeatureOverride("Videos", true);
// Enable all feature overrides affected by new servers
SetFeatureOverride("Apps", true);
SetFeatureOverride("Channels", true);
SetFeatureOverride("Games", true);
SetFeatureOverride("Marketplace", true);
SetFeatureOverride("Music", true);
SetFeatureOverride("MusicVideos", true);
SetFeatureOverride("Podcasts", true);
SetFeatureOverride("Social", true);
SetFeatureOverride("Videos", true);
return Task.FromResult(true);
return Task.FromResult<string?>(null);
}
catch (UnauthorizedAccessException)
{
return Task.FromResult<string?>($"Failed to open '{zsDllInfo.FullName}'. Verify that the Zune software is not running and try again.");
}
catch (Exception ex)
{
return Task.FromResult<string?>(ex.Message);
}
}
public override Task<bool> Reset()
public override Task<string?> Reset()
{
throw new NotImplementedException();
}