Decompiled source of CustomPaintings v1.0.0

CustomPaintings.dll

Decompiled 9 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Decorators;
using PluginConfig.API.Fields;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CustomPaintings")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ea98faf9271e0bc46962792138f494db6f51e993")]
[assembly: AssemblyProduct("CustomPaintings")]
[assembly: AssemblyTitle("CustomPaintings")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CustomPaintings
{
	public enum ReplacementStrategy
	{
		DeterministicRelaxedBestFit,
		RandomRelaxedBestFit,
		StrictBestFit,
		Random
	}
	public class ConfigManager : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static PostStringValueChangeEvent <>9__4_0;

			public static PostEnumValueChangeEvent<ReplacementStrategy> <>9__4_1;

			public static PostFloatValueChangeEvent <>9__4_2;

			internal void <Init>b__4_0(string _)
			{
				Replacer.LoadCustomImages();
				Replacer.DoReplacements();
			}

			internal void <Init>b__4_1(ReplacementStrategy _)
			{
				Replacer.DoReplacements();
			}

			internal void <Init>b__4_2(float _)
			{
				Replacer.DoReplacements();
			}
		}

		public static PluginConfigurator PConf;

		public static StringField CustomImageDir;

		public static EnumField<ReplacementStrategy> ReplacementStrategy;

		public static FloatField FitAspectRatioRelax;

		public static void Init()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Expected O, but got Unknown
			if (PConf != null)
			{
				return;
			}
			PConf = PluginConfigurator.Create("Custom Paintings", "com.github.end-4.customPaintings");
			string text = Path.Combine(Core.workingDir, "icon.png");
			if (File.Exists(text))
			{
				PConf.SetIconWithURL(text);
			}
			new ConfigHeader(PConf.rootPanel, "", 10);
			new ConfigHeader(PConf.rootPanel, "-- CUSTOM PAINTINGS --", 24);
			new ConfigHeader(PConf.rootPanel, "- Absolutely make sure the path is correct!\n- Allowed image types are PNG and JPG", 12, (TextAlignmentOptions)513);
			CustomImageDir = new StringField(PConf.rootPanel, "Image pool folder", "folderPath", Path.Combine(Core.workingDir, "assets/defaultPool"));
			StringField customImageDir = CustomImageDir;
			object obj = <>c.<>9__4_0;
			if (obj == null)
			{
				PostStringValueChangeEvent val = delegate
				{
					Replacer.LoadCustomImages();
					Replacer.DoReplacements();
				};
				<>c.<>9__4_0 = val;
				obj = (object)val;
			}
			customImageDir.postValueChangeEvent += (PostStringValueChangeEvent)obj;
			ReplacementStrategy = new EnumField<ReplacementStrategy>(PConf.rootPanel, "Replacement strategy", "replacementStrategy", CustomPaintings.ReplacementStrategy.RandomRelaxedBestFit);
			ReplacementStrategy.postValueChangeEvent += delegate
			{
				Replacer.DoReplacements();
			};
			FitAspectRatioRelax = new FloatField(PConf.rootPanel, "Fit aspect ratio relax amount", "fitAspectRatioRelax", 0.3f);
			FloatField fitAspectRatioRelax = FitAspectRatioRelax;
			object obj2 = <>c.<>9__4_2;
			if (obj2 == null)
			{
				PostFloatValueChangeEvent val2 = delegate
				{
					Replacer.DoReplacements();
				};
				<>c.<>9__4_2 = val2;
				obj2 = (object)val2;
			}
			fitAspectRatioRelax.postValueChangeEvent += (PostFloatValueChangeEvent)obj2;
			new ConfigHeader(PConf.rootPanel, "", 30);
			new ConfigHeader(PConf.rootPanel, "The artworks bundled with this mod are by Ravimo and licensed under CC-BY 4.0\n\nRavimo: https://www.pixiv.net/en/users/60562229/illustrations\nLicense: https://creativecommons.org/licenses/by/4.0/deed", 10, (TextAlignmentOptions)513);
			Core.Log.LogInfo((object)"ConfigManager initialized");
		}
	}
	[BepInPlugin("com.github.end-4.customPaintings", "CustomPaintings", "1.0.0")]
	public class Core : BaseUnityPlugin
	{
		public static string workingPath = Assembly.GetExecutingAssembly().Location;

		public static string workingDir = Path.GetDirectoryName(workingPath);

		internal static ManualLogSource Log;

		public const string PluginGUID = "com.github.end-4.customPaintings";

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigManager.Init();
			Replacer.LoadCustomImages();
			Replacer.DoReplacements();
			SceneManager.sceneLoaded += Replacer.DoReplacements;
			Log.LogInfo((object)"CustomPaintings loaded!");
		}
	}
	public class Replacer : BaseUnityPlugin
	{
		private struct CustomTexture
		{
			public Texture2D texture;

			public float aspectRatio;

			public string name;
		}

		private static readonly List<string> MaterialPaths = new List<string>(38)
		{
			"Assets/Materials/Environment/Layer 1/StainedGlassBig.mat", "Assets/Materials/Environment/Layer 1/StainedGlassBigTransparent.mat", "Assets/Materials/Environment/Layer 1/StainedGlassBlue.mat", "Assets/Materials/Environment/Layer 1/StainedGlassGabriel1.mat", "Assets/Materials/Environment/Layer 1/StainedGlassLit.mat", "Assets/Materials/Environment/Layer 1/StainedGlassRed.mat", "Assets/Materials/Environment/Paintings/045.mat", "Assets/Materials/Environment/Paintings/101.mat", "Assets/Materials/Environment/Paintings/118.mat", "Assets/Materials/Environment/Paintings/161.mat",
			"Assets/Materials/Environment/Paintings/166.mat", "Assets/Materials/Environment/Paintings/203.mat", "Assets/Materials/Environment/Paintings/208.mat", "Assets/Materials/Environment/Paintings/209.mat", "Assets/Materials/Environment/Paintings/210.mat", "Assets/Materials/Environment/Paintings/223.mat", "Assets/Materials/Environment/Paintings/226.mat", "Assets/Materials/Environment/Paintings/285.mat", "Assets/Materials/Environment/Paintings/286.mat", "Assets/Materials/Environment/Paintings/287.mat",
			"Assets/Materials/Environment/Paintings/Archangels.mat", "Assets/Materials/Environment/Paintings/CityoftheDeadSunPoster.mat", "Assets/Materials/Environment/Paintings/Default.mat", "Assets/Materials/Environment/Paintings/Ferryman.mat", "Assets/Materials/Environment/Paintings/FerrymanGabriel.mat", "Assets/Materials/Environment/Paintings/FerrymanGabrielDestroyed.mat", "Assets/Materials/Environment/Paintings/FerrymanMirror.mat", "Assets/Materials/Environment/Paintings/FerrymanRocket.mat", "Assets/Materials/Environment/Paintings/KingMinos.mat", "Assets/Materials/Environment/Paintings/KingSisyphus.mat",
			"Assets/Materials/Environment/Paintings/Leviathan.mat", "Assets/Materials/Environment/Paintings/VanGogh.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Clothes.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Clothes NoFog.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Fox.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Fox NoFog.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Wing.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Wing NoFog.mat"
		};

		private static List<CustomTexture> CustomTextures = new List<CustomTexture>();

		private static Dictionary<Material, Vector2> MatDimensions = new Dictionary<Material, Vector2>();

		private static int GetDeterministicHash(string input, int max)
		{
			using SHA256 sHA = SHA256.Create();
			return Math.Abs(BitConverter.ToInt32(sHA.ComputeHash(Encoding.UTF8.GetBytes(input)), 0)) % max;
		}

		private static CustomTexture FindBestMatch(float targetAspectRatio, string targetName)
		{
			foreach (CustomTexture customTexture in CustomTextures)
			{
				if (customTexture.name.Equals(targetName, StringComparison.OrdinalIgnoreCase))
				{
					return customTexture;
				}
			}
			CustomTexture result = CustomTextures[0];
			if (ConfigManager.ReplacementStrategy.value == ReplacementStrategy.DeterministicRelaxedBestFit || ConfigManager.ReplacementStrategy.value == ReplacementStrategy.RandomRelaxedBestFit || ConfigManager.ReplacementStrategy.value == ReplacementStrategy.StrictBestFit)
			{
				float num = Mathf.Abs(targetAspectRatio - result.aspectRatio);
				List<int> list = new List<int>();
				for (int i = 0; i < CustomTextures.Count; i++)
				{
					float num2 = Mathf.Abs(targetAspectRatio - CustomTextures[i].aspectRatio);
					if (num2 <= ConfigManager.FitAspectRatioRelax.value)
					{
						list.Add(i);
					}
					else if (num2 < num)
					{
						num = num2;
						result = CustomTextures[i];
					}
				}
				if (ConfigManager.ReplacementStrategy.value != ReplacementStrategy.StrictBestFit && list.Count > 0)
				{
					int index = ((ConfigManager.ReplacementStrategy.value != 0) ? Random.Range(0, list.Count) : GetDeterministicHash(targetName, list.Count));
					result = CustomTextures[list[index]];
				}
			}
			else if (ConfigManager.ReplacementStrategy.value == ReplacementStrategy.Random)
			{
				result = CustomTextures[Random.Range(0, CustomTextures.Count)];
			}
			return result;
		}

		private static void ReplaceTexture(Material toReplace, string assetPath)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)toReplace == (Object)null) && !((Object)(object)toReplace.mainTexture == (Object)null) && CustomTextures.Count != 0)
			{
				if (!MatDimensions.ContainsKey(toReplace))
				{
					MatDimensions.Add(toReplace, new Vector2((float)toReplace.mainTexture.width, (float)toReplace.mainTexture.height));
				}
				float num = MatDimensions[toReplace].x / MatDimensions[toReplace].y;
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(assetPath);
				CustomTexture customTexture = FindBestMatch(num, fileNameWithoutExtension);
				toReplace.mainTexture = (Texture)(object)customTexture.texture;
				Vector2 one = Vector2.one;
				Vector2 zero = Vector2.zero;
				if (customTexture.aspectRatio > num)
				{
					one.x = num / customTexture.aspectRatio;
					zero.x = (1f - one.x) / 2f;
				}
				else
				{
					one.y = customTexture.aspectRatio / num;
					zero.y = (1f - one.y) / 2f;
				}
				toReplace.mainTextureScale = one;
				toReplace.mainTextureOffset = zero;
			}
		}

		public static void LoadCustomImages()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			CustomTextures.Clear();
			string value = ConfigManager.CustomImageDir.value;
			if (Directory.Exists(value))
			{
				string[] files = Directory.GetFiles(value, "*.*", SearchOption.AllDirectories);
				foreach (string path in files)
				{
					switch (Path.GetExtension(path).ToLower())
					{
					case ".png":
					case ".jpg":
					case ".jpeg":
					{
						byte[] array = File.ReadAllBytes(path);
						Texture2D val = new Texture2D(2, 2);
						if (ImageConversion.LoadImage(val, array))
						{
							CustomTextures.Add(new CustomTexture
							{
								texture = val,
								aspectRatio = (float)((Texture)val).width / (float)((Texture)val).height,
								name = Path.GetFileNameWithoutExtension(path)
							});
						}
						break;
					}
					}
				}
			}
			if (CustomTextures.Count == 0)
			{
				Core.Log.LogWarning((object)("No custom images found in " + value));
			}
			else
			{
				Core.Log.LogInfo((object)$"Loaded {CustomTextures.Count} custom images");
			}
		}

		private static void ReplaceMaterialAssets()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < MaterialPaths.Count; i++)
			{
				string text = MaterialPaths[i];
				ReplaceTexture(Addressables.LoadAssetAsync<Material>((object)text).WaitForCompletion(), text);
			}
		}

		public static void DoReplacements()
		{
			ReplaceMaterialAssets();
		}

		public static void DoReplacements(Scene scene, LoadSceneMode mode)
		{
			DoReplacements();
		}
	}
	public class ExportUtils
	{
		private static string SafeFileName(string s)
		{
			return s.Replace("/", "-");
		}

		public static void ExportMaterialTexture(Material mat, string folderPath, string namePrefix = "")
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			//IL_018f: Expected O, but got Unknown
			if ((Object)(object)mat == (Object)null || (Object)(object)mat.mainTexture == (Object)null)
			{
				Core.Log.LogError((object)"Material or Main Texture is missing.");
				return;
			}
			if (((Object)mat).name.StartsWith("Hidden"))
			{
				Core.Log.LogError((object)"Not exporting hidden material.");
				return;
			}
			Core.Log.LogInfo((object)("Exporting material: " + ((Object)mat).name + " with mainTexture: " + ((Object)mat.mainTexture).name));
			if (!Directory.Exists(folderPath))
			{
				Directory.CreateDirectory(folderPath);
			}
			Texture mainTexture = mat.mainTexture;
			if (mainTexture.width == 0 || mainTexture.height == 0)
			{
				Core.Log.LogError((object)"Texture is empty, skipping.");
				return;
			}
			Core.Log.LogInfo((object)$"Texture size {mainTexture.width}x{mainTexture.height}");
			RenderTexture temporary = RenderTexture.GetTemporary(mainTexture.width, mainTexture.height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)1);
			Graphics.Blit(mainTexture, temporary);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D(mainTexture.width, mainTexture.height);
			val.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			byte[] bytes = ImageConversion.EncodeToPNG(val);
			string path = SafeFileName(namePrefix + ((Object)mat).name + ".png");
			string text = Path.Combine(folderPath, path);
			File.WriteAllBytes(text, bytes);
			Core.Log.LogInfo((object)("Texture exported successfully to: " + text));
			Object.DestroyImmediate((Object)val);
		}

		public static void ExportImageToPNG(Image uiImage, string folderPath, string namePrefix = "")
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_012a: Expected O, but got Unknown
			if ((Object)(object)uiImage == (Object)null || (Object)(object)uiImage.sprite == (Object)null)
			{
				Core.Log.LogError((object)"Image component or Sprite is missing.");
				return;
			}
			if (!Directory.Exists(folderPath))
			{
				Directory.CreateDirectory(folderPath);
			}
			Sprite sprite = uiImage.sprite;
			Texture2D texture = sprite.texture;
			Rect rect = sprite.rect;
			int num = (int)((Rect)(ref rect)).width;
			rect = sprite.rect;
			int num2 = (int)((Rect)(ref rect)).height;
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)1);
			Graphics.Blit((Texture)(object)texture, temporary);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D(num, num2);
			rect = sprite.rect;
			float x = ((Rect)(ref rect)).x;
			rect = sprite.rect;
			val.ReadPixels(new Rect(x, ((Rect)(ref rect)).y, (float)num, (float)num2), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			byte[] bytes = ImageConversion.EncodeToPNG(val);
			string path = SafeFileName(namePrefix + ((Object)uiImage).name + ".png");
			string text = Path.Combine(folderPath, path);
			File.WriteAllBytes(text, bytes);
			Core.Log.LogInfo((object)("UI Image exported to: " + text));
			Object.DestroyImmediate((Object)val);
		}
	}
}