From abd9d37986617dbf05018d502df568be5ad21be4 Mon Sep 17 00:00:00 2001 From: Miepee Date: Wed, 18 Jan 2023 13:30:01 +0100 Subject: [PATCH] Make icons+splashes internal, only read external if they're provided --- AM2RPortHelperLib/AM2RPortHelperLib.csproj | 15 ++++ AM2RPortHelperLib/HelperMethods.cs | 4 +- AM2RPortHelperLib/IMods.cs | 2 +- AM2RPortHelperLib/RawMods.cs | 68 +++++++++++---- AM2RPortHelperLib/Resources.Designer.cs | 78 ++++++++++++++++++ AM2RPortHelperLib/Resources.resx | 30 +++++++ .../{utils => Resources}/icon.png | Bin .../{utils => Resources}/splash.png | Bin .../{utils => Resources}/splashAndroid.png | Bin 9 files changed, 178 insertions(+), 19 deletions(-) create mode 100644 AM2RPortHelperLib/Resources.Designer.cs create mode 100644 AM2RPortHelperLib/Resources.resx rename AM2RPortHelperLib/{utils => Resources}/icon.png (100%) rename AM2RPortHelperLib/{utils => Resources}/splash.png (100%) rename AM2RPortHelperLib/{utils => Resources}/splashAndroid.png (100%) diff --git a/AM2RPortHelperLib/AM2RPortHelperLib.csproj b/AM2RPortHelperLib/AM2RPortHelperLib.csproj index caba697..d242e7e 100644 --- a/AM2RPortHelperLib/AM2RPortHelperLib.csproj +++ b/AM2RPortHelperLib/AM2RPortHelperLib.csproj @@ -28,4 +28,19 @@ + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + True + True + Resources#.resx + + + diff --git a/AM2RPortHelperLib/HelperMethods.cs b/AM2RPortHelperLib/HelperMethods.cs index 1d8cfaf..3ea96f7 100644 --- a/AM2RPortHelperLib/HelperMethods.cs +++ b/AM2RPortHelperLib/HelperMethods.cs @@ -73,7 +73,7 @@ public static class HelperMethods /// The filepath where the resized image should be saved to. /// /// - /// Image iconPath = Image.Load("iconPath.png"); + /// string iconPath = "iconPath.png"; /// SaveAndroidIcon(iconPath, 128, "128.png"); /// /// @@ -84,7 +84,7 @@ public static class HelperMethods picture.Mutate(x => x.Resize(dimensions, dimensions, KnownResamplers.NearestNeighbor)); picture.SaveAsPng(filePath); } - + /// /// Calculates the SHA256 hash of a specified file. /// diff --git a/AM2RPortHelperLib/IMods.cs b/AM2RPortHelperLib/IMods.cs index 078d917..5d1955b 100644 --- a/AM2RPortHelperLib/IMods.cs +++ b/AM2RPortHelperLib/IMods.cs @@ -14,7 +14,7 @@ public abstract class IMods /// /// A temporary directory /// - protected static readonly string tmp = Path.GetTempPath(); + protected static readonly string tmp = Path.GetTempPath() + "/PortHelper/"; /// /// The current directory of the AM2RPortHelper program. diff --git a/AM2RPortHelperLib/RawMods.cs b/AM2RPortHelperLib/RawMods.cs index 1963279..eba67d8 100644 --- a/AM2RPortHelperLib/RawMods.cs +++ b/AM2RPortHelperLib/RawMods.cs @@ -1,7 +1,9 @@ using System.Diagnostics; using System.IO.Compression; using System.Runtime.InteropServices; +using System.Security; using System.Text.RegularExpressions; +using SixLabors.ImageSharp; using UndertaleModLib; using static AM2RPortHelperLib.Core; @@ -29,7 +31,41 @@ public abstract class RawMods : IMods throw new NotSupportedException("The OS of the mod zip is unknown and thus not supported"); } - + + private static string GetProperPathToBuiltinIcons(string nameOfResource) + { + string subCaseFunction(string resource) + { + // TODO: default path should be in XDG_CONFIG + string origPath = utilDir + "/" + resource; + if (File.Exists(origPath)) + return origPath; + + var byteArray = resource switch + { + nameof(Resources.icon) + ".png" => Resources.icon, + nameof(Resources.splash) + ".png" => Resources.splash, + nameof(Resources.splashAndroid) + ".png" => Resources.splashAndroid, + _ => throw new InvalidDataException("SubCaseFunction was called with an improper resource!") + }; + + Image.Load(byteArray).SaveAsPng(tmp + "/" + resource); + origPath = tmp + "/" + resource; + return origPath; + } + + switch (nameOfResource) + { + case nameof(Resources.icon): + return subCaseFunction(nameof(Resources.icon) + ".png"); + case nameof(Resources.splash): + return subCaseFunction(nameof(Resources.splash) + ".png"); + case nameof(Resources.splashAndroid): + return subCaseFunction(nameof(Resources.splashAndroid) + ".png"); + default: throw new InvalidDataException(nameOfResource + " is an unknown Icon!"); + } + } + // TODO: Port to Windows public static void PortToWindows(string inputRawZipPath, string outputRawZipPath, OutputHandlerDelegate outputHandlerDelegate = null) { @@ -82,9 +118,9 @@ public abstract class RawMods : IMods File.Copy(utilDir + "/runner", extractDirectory + "/runner"); if (!File.Exists(assetsDir + "/icon.png")) - File.Copy(utilDir + "/icon.png", assetsDir + "/icon.png"); + File.Copy(GetProperPathToBuiltinIcons(nameof(Resources.icon)), assetsDir + "/icon.png"); if (!File.Exists(assetsDir + "/splash.png")) - File.Copy(utilDir + "/splash.png", assetsDir + "/splash.png"); + File.Copy(GetProperPathToBuiltinIcons(nameof(Resources.splash)), assetsDir + "/splash.png"); //recursively lowercase everything in the assets folder HelperMethods.LowercaseFolder(assetsDir); @@ -94,7 +130,7 @@ public abstract class RawMods : IMods ZipFile.CreateFromDirectory(extractDirectory, outputRawZipPath); // Clean up - Directory.Delete(assetsDir, true); + Directory.Delete(tmp, true); } public static void PortToAndroid(string inputRawZipPath, string outputRawApkPath, bool useCustomSaveDirectory = false, bool usesInternet = false, OutputHandlerDelegate outputDelegate = null) @@ -104,7 +140,6 @@ public abstract class RawMods : IMods outputHandler = outputDelegate; string extractDirectory = tmp + "/" + Path.GetFileNameWithoutExtension(inputRawZipPath); - string unzipDir = extractDirectory + "/zip"; string apkDir = extractDirectory + "/apk"; string apkAssetsDir = apkDir + "/assets"; string bin = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "cmd.exe" : "java"; @@ -160,8 +195,8 @@ public abstract class RawMods : IMods default: throw new NotSupportedException("The OS of the mod zip is unknown and thus not supported"); } - if (!File.Exists(apkAssetsDir + "/splash.png")) - File.Copy(utilDir + "/splashAndroid.png", apkAssetsDir + "/splash.png", true); + // The wrapper always has a splash image, so we want to overwrite it. + File.Copy(GetProperPathToBuiltinIcons(nameof(Resources.splashAndroid)), apkAssetsDir + "/splash.png", true); //recursively lowercase everything in the assets folder HelperMethods.LowercaseFolder(apkAssetsDir); @@ -171,10 +206,10 @@ public abstract class RawMods : IMods yamlFile = yamlFile.Replace("doNotCompress:", "doNotCompress:\n- ogg"); File.WriteAllText(apkDir + "/apktool.yml", yamlFile); - // Edit the icons in the apk + // Edit the icons in the apk. Wrapper always has these, so we need to overwrite these too. string resPath = apkDir + "/res"; - // TODO: icon should only be read from if its there, otherwise default frog icon should be in the assembly - string origPath = utilDir + "/icon.png"; + // Icon should only be read from if its there, otherwise default frog icon should be in the assembly + string origPath = GetProperPathToBuiltinIcons(nameof(Resources.icon)); HelperMethods.SaveAndroidIcon(origPath, 96, resPath + "/drawable/icon.png"); HelperMethods.SaveAndroidIcon(origPath, 72, resPath + "/drawable-hdpi-v4/icon.png"); HelperMethods.SaveAndroidIcon(origPath, 36, resPath + "/drawable-ldpi-v4/icon.png"); @@ -273,7 +308,7 @@ public abstract class RawMods : IMods File.Move(finalApkBuild, outputRawApkPath); // Clean up - Directory.Delete(extractDirectory, true); + Directory.Delete(tmp, true); } public static void PortToMac(string inputRawZipPath, string outputRawZipPath, OutputHandlerDelegate outputDelegate = null) @@ -324,10 +359,11 @@ public abstract class RawMods : IMods default: throw new NotSupportedException("The OS of the mod zip is unknown and thus not supported"); } + // TODO: do we really want to keep their images? if (!File.Exists(assetsDir + "/icon.png")) - File.Copy(utilDir + "/icon.png", extractDirectory + "/icon.png"); + File.Copy(GetProperPathToBuiltinIcons(nameof(Resources.icon)), extractDirectory + "/icon.png"); if (!File.Exists(assetsDir + "/splash.png")) - File.Copy(utilDir + "/splash.png", extractDirectory + "/splash.png"); + File.Copy(GetProperPathToBuiltinIcons(nameof(Resources.splash)), extractDirectory + "/splash.png"); // Delete fonts folder if it exists, because I need to convert bytecode version from game and newer version doesn't support font loading if (Directory.Exists(extractDirectory + "/lang/fonts")) @@ -379,8 +415,8 @@ public abstract class RawMods : IMods UndertaleData gmData = UndertaleIO.Read(fs, SendOutput, SendOutput); modName = gmData.GeneralInfo.DisplayName.Content; } - //TODO: handle error on special characters, but need to know which characters are invalid in the first place - //if (modName.Contains()) + // Escape invalid xml characters + modName = SecurityElement.Escape(modName); SendOutput("Editing Runner references to AM2R..."); string textFile = File.ReadAllText(assetsDir + "/yoyorunner.config"); textFile = textFile.Replace("YoYo Runner", modName); @@ -401,6 +437,6 @@ public abstract class RawMods : IMods ZipFile.CreateFromDirectory(baseTempDirectory, outputRawZipPath); // Clean up - Directory.Delete(baseTempDirectory, true); + Directory.Delete(tmp, true); } } \ No newline at end of file diff --git a/AM2RPortHelperLib/Resources.Designer.cs b/AM2RPortHelperLib/Resources.Designer.cs new file mode 100644 index 0000000..333e613 --- /dev/null +++ b/AM2RPortHelperLib/Resources.Designer.cs @@ -0,0 +1,78 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AM2RPortHelperLib { + using System; + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [System.Diagnostics.DebuggerNonUserCodeAttribute()] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static System.Resources.ResourceManager resourceMan; + + private static System.Globalization.CultureInfo resourceCulture; + + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Resources.ResourceManager ResourceManager { + get { + if (object.Equals(null, resourceMan)) { + System.Resources.ResourceManager temp = new System.Resources.ResourceManager("AM2RPortHelperLib.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] icon { + get { + object obj = ResourceManager.GetObject("icon", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] splash { + get { + object obj = ResourceManager.GetObject("splash", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] splashAndroid { + get { + object obj = ResourceManager.GetObject("splashAndroid", resourceCulture); + return ((byte[])(obj)); + } + } + } +} \ No newline at end of file diff --git a/AM2RPortHelperLib/Resources.resx b/AM2RPortHelperLib/Resources.resx new file mode 100644 index 0000000..572ed8f --- /dev/null +++ b/AM2RPortHelperLib/Resources.resx @@ -0,0 +1,30 @@ + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Resources\icon.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Resources\splash.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Resources\splashAndroid.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AM2RPortHelperLib/utils/icon.png b/AM2RPortHelperLib/Resources/icon.png similarity index 100% rename from AM2RPortHelperLib/utils/icon.png rename to AM2RPortHelperLib/Resources/icon.png diff --git a/AM2RPortHelperLib/utils/splash.png b/AM2RPortHelperLib/Resources/splash.png similarity index 100% rename from AM2RPortHelperLib/utils/splash.png rename to AM2RPortHelperLib/Resources/splash.png diff --git a/AM2RPortHelperLib/utils/splashAndroid.png b/AM2RPortHelperLib/Resources/splashAndroid.png similarity index 100% rename from AM2RPortHelperLib/utils/splashAndroid.png rename to AM2RPortHelperLib/Resources/splashAndroid.png