Decompiled source of RetexturePlugin v3.0.0

RetexturePlugin.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Bounce.Singletons;
using ModdingTales;
using SRF;
using UnityEngine;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("RetexturePlugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RetexturePlugin")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("RetexturePlugin")]
[assembly: ComVisible(false)]
[assembly: Guid("c303405d-e66c-4316-9cdb-4e3ca15c6360")]
[assembly: AssemblyFileVersion("3.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("3.0.0.0")]
namespace LordAshes;

[BepInPlugin("org.lordashes.plugins.retexture", "Retexture Plug-In", "3.0.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class RetexturePlugin : BaseUnityPlugin
{
	public static class Utility
	{
		public static bool isBoardLoaded()
		{
			return SimpleSingletonBehaviour<CameraController>.HasInstance && SingletonStateMBehaviour<BoardSessionManager, State<BoardSessionManager>>.HasInstance && !BoardSessionManager.IsLoading;
		}

		public static float ParseFloat(string value)
		{
			return float.Parse(value, CultureInfo.InvariantCulture);
		}

		public static object FindObjectInHierarchy<T>(GameObject start, string fullName = null, string partialName = null)
		{
			return FindObjectsInHierarchy<T>(start, fullName, partialName)?.ElementAt(0);
		}

		public static object[] FindObjectsInHierarchy<T>(GameObject start, string fullName = null, string partialName = null)
		{
			List<object> results = new List<object>();
			Traverse<T>(start, ref results, fullName, partialName);
			if (results.Count > 0)
			{
				return results.ToArray();
			}
			return null;
		}

		public static void Traverse<T>(GameObject start, ref List<object> results, string fullName = null, string partialName = null)
		{
			LoggingPlugin.LogDebug("Found GameObject " + ((Object)start).name + " (" + ((Object)start.transform).name + ") While Seeking " + typeof(T).ToString() + " With Name " + ((fullName == null) ? "Unspecified" : fullName) + " And Parial Name " + ((partialName == null) ? "Unspecified" : partialName));
			if (((object)start).GetType() == typeof(T) && (fullName == null || ((Object)start).name == fullName) && (partialName == null || ((Object)start).name.Contains(partialName)))
			{
				LoggingPlugin.LogDebug("Adding GameObject " + ((Object)start).name + " To Results");
				results.Add(start);
			}
			Component[] components = start.GetComponents(typeof(T));
			foreach (Component val in components)
			{
				LoggingPlugin.LogDebug("Found GameObject " + ((Object)start).name + " (" + ((Object)start.transform).name + ") Component " + ((Object)val).name + " (" + ((object)val).GetType().ToString() + ") While Seeking " + typeof(T).ToString() + " With Name " + ((fullName == null) ? "Unspecified" : fullName) + " And Parial Name " + ((partialName == null) ? "Unspecified" : partialName));
				if ((fullName == null || ((Object)start).name == fullName) && (partialName == null || ((Object)start).name.Contains(partialName)))
				{
					LoggingPlugin.LogDebug("Assing GameObject " + ((Object)start).name + " Component " + ((Object)val).name + " To Results");
					results.Add(val);
				}
			}
			foreach (Transform child in SRFTransformExtensions.GetChildren(start.transform))
			{
				Traverse<T>(((Component)child).gameObject, ref results, fullName, partialName);
			}
		}

		public static GameObject FindObjectWithInHierarchy<T>(GameObject start, string fullName = null, string partialName = null)
		{
			return FindObjectsWithInHierarchy<T>(start, fullName, partialName)?.ElementAt(0);
		}

		public static GameObject[] FindObjectsWithInHierarchy<T>(GameObject start, string fullName = null, string partialName = null)
		{
			List<GameObject> results = new List<GameObject>();
			TraverseWith<T>(start, ref results, fullName, partialName);
			if (results.Count > 0)
			{
				return results.ToArray();
			}
			return null;
		}

		public static void TraverseWith<T>(GameObject start, ref List<GameObject> results, string fullName = null, string partialName = null)
		{
			LoggingPlugin.LogDebug("Found GameObject " + ((Object)start).name + " (" + ((Object)start.transform).name + ") While Seeking " + typeof(T).ToString() + " With Name " + ((fullName == null) ? "Unspecified" : fullName) + " And Parial Name " + ((partialName == null) ? "Unspecified" : partialName));
			if (((object)start).GetType() == typeof(T) && (fullName == null || ((Object)start).name == fullName) && (partialName == null || ((Object)start).name.Contains(partialName)))
			{
				LoggingPlugin.LogDebug("Adding GameObject " + ((Object)start).name + " To Results");
				results.Add(start);
			}
			Component[] components = start.GetComponents(typeof(T));
			foreach (Component val in components)
			{
				LoggingPlugin.LogDebug("Found GameObject " + ((Object)start).name + " (" + ((Object)start.transform).name + ") Component " + ((Object)val).name + " (" + ((object)val).GetType().ToString() + ") While Seeking " + typeof(T).ToString() + " With Name " + ((fullName == null) ? "Unspecified" : fullName) + " And Parial Name " + ((partialName == null) ? "Unspecified" : partialName));
				if ((fullName == null || ((Object)start).name == fullName) && (partialName == null || ((Object)start).name.Contains(partialName)))
				{
					LoggingPlugin.LogDebug("Adding GameObject " + ((Object)start).name + " Component To Results");
					results.Add(start);
				}
			}
			foreach (Transform child in SRFTransformExtensions.GetChildren(start.transform))
			{
				TraverseWith<T>(((Component)child).gameObject, ref results, fullName, partialName);
			}
		}

		public static object LookUp(in Dictionary<string, object> dictionary, string key)
		{
			foreach (KeyValuePair<string, object> item in dictionary)
			{
				if (item.Key.ToUpper() == key.ToUpper())
				{
					return item.Value;
				}
			}
			return null;
		}

		public static void PostOnMainPage(BaseUnityPlugin plugin)
		{
			string text = "Lord Ashes" + ("Lord Ashes".ToUpper().EndsWith("S") ? "'" : "'s");
			ModdingUtils.AddPluginToMenuList(plugin, text);
		}
	}

	public const string Name = "Retexture Plug-In";

	public const string Guid = "org.lordashes.plugins.retexture";

	public const string Version = "3.0.0.0";

	public const string Author = "Lord Ashes";

	private Dictionary<CreatureGuid, Material> originalMaterials = new Dictionary<CreatureGuid, Material>();

	private Guid subscriptionId = System.Guid.Empty;

	private ConfigEntry<KeyboardShortcut> triggerKey { get; set; }

	private ConfigEntry<KeyboardShortcut> triggerResetKey { get; set; }

	private void Awake()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		LoggingPlugin.SetLogLevel(((BaseUnityPlugin)this).Config.Bind<DiagnosticLevel>("Settings", "Diagnostic Level", (DiagnosticLevel)3, (ConfigDescription)null).Value);
		string? assemblyQualifiedName = ((object)this).GetType().AssemblyQualifiedName;
		DiagnosticLevel logLevel = LoggingPlugin.GetLogLevel();
		LoggingPlugin.LogInfo(assemblyQualifiedName + ": Active. (Diagnostic Mode = " + ((object)(DiagnosticLevel)(ref logLevel)).ToString() + ")");
		triggerKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Repaint Asset Activation", new KeyboardShortcut((KeyCode)120, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), (ConfigDescription)null);
		triggerResetKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Transform (Recall) Repainted", new KeyboardShortcut((KeyCode)121, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), (ConfigDescription)null);
		AssetDataPlugin.Subscribe("org.lordashes.plugins.retexture", (Action<DatumChange>)RequestHandler, (Func<DatumChange, bool>)Checker.CheckSourceAsCreature);
		Utility.PostOnMainPage((BaseUnityPlugin)(object)this);
	}

	private void Update()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		KeyboardShortcut value = triggerKey.Value;
		if (((KeyboardShortcut)(ref value)).IsUp())
		{
			LoggingPlugin.LogDebug("Make Retexture Request For Selected Mini");
			CreatureBoardAsset asset = default(CreatureBoardAsset);
			CreaturePresenter.TryGetAsset(LocalClient.SelectedCreatureId, ref asset);
			if ((Object)(object)asset != (Object)null)
			{
				SystemMessage.AskForTextInput("Replacement Texture...", "\r\nSource:", "Texture", (Action<string>)delegate(string source)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					CreatureGuid creatureId2 = asset.CreatureId;
					AssetDataPlugin.SetInfo(((object)(CreatureGuid)(ref creatureId2)).ToString(), "org.lordashes.plugins.retexture", source, false);
				}, (Action)null, "Original", (Action)delegate
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					CreatureGuid creatureId = asset.CreatureId;
					AssetDataPlugin.ClearInfo(((object)(CreatureGuid)(ref creatureId)).ToString(), "org.lordashes.plugins.retexture", false);
				}, "");
			}
			else
			{
				SystemMessage.DisplayInfoText("Retexture Plugin Requires A Selected Mini", 2.5f, 0f, (Action)null);
			}
		}
		value = triggerResetKey.Value;
		if (((KeyboardShortcut)(ref value)).IsUp())
		{
			LoggingPlugin.LogDebug("Reset Retexture Subscription");
			if (subscriptionId != System.Guid.Empty)
			{
				AssetDataPlugin.Unsubscribe(subscriptionId);
				AssetDataPlugin.Subscribe("org.lordashes.plugins.retexture", (Action<DatumChange>)RequestHandler, (Func<DatumChange, bool>)Checker.CheckSourceAsCreature);
			}
		}
	}

	private void RequestHandler(DatumChange change)
	{
		//IL_006c: 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_00b5: Expected O, but got Unknown
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Invalid comparison between Unknown and I4
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Expected O, but got Unknown
		if (change.source != null && change.source != "" && change.key != null && change.value != null)
		{
			LoggingPlugin.LogDebug("Request To Retexture " + change.source + " To " + change.value);
			CreatureBoardAsset val = null;
			CreaturePresenter.TryGetAsset(new CreatureGuid(change.source), ref val);
			Material val2 = null;
			GameObject val3 = Utility.FindObjectWithInHierarchy<GameObject>(((Component)val).gameObject, null, "Effect:");
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = (GameObject)Utility.FindObjectInHierarchy<GameObject>(((Component)val).gameObject, null, "_Rotator");
				bool flag = val3.GetComponentsInChildren<MeshFilter>().Any((MeshFilter mf) => StartsWithGuid(((Object)mf).name));
				LoggingPlugin.LogDebug("Asset Is ANGEL Asset? " + ((Behaviour)this).isActiveAndEnabled);
				if (!flag)
				{
					val3 = (GameObject)Utility.FindObjectInHierarchy<GameObject>(((Component)val).gameObject, null, "local[br");
				}
				LoggingPlugin.LogDebug("Starting Asset Seek At " + ((Object)val3).name);
			}
			else
			{
				LoggingPlugin.LogDebug("Starting Effect Seek At " + ((Object)val3).name);
			}
			val2 = FindMaterial(val3, "RETEXTURE_MAT");
			LoggingPlugin.LogDebug("Modifying " + ((Object)val2).name + ", Texture " + ((Object)val2.mainTexture).name + ", Shader " + ((Object)val2.shader).name);
			if ((int)change.action != 1 && (Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
			{
				ApplyTexture(val, val3, val2, change.value.ToString());
			}
			else if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
			{
				RestoreTexture(val, val3, val2);
			}
		}
		else
		{
			LoggingPlugin.LogWarning("Retexture Request Incomplete");
			if (change.source == null || change.source == "")
			{
				LoggingPlugin.LogWarning("Retexture Request Missing Souce");
			}
			if (change.key == null)
			{
				LoggingPlugin.LogWarning("Retexture Request Missing Key");
			}
			if (change.value == null)
			{
				LoggingPlugin.LogWarning("Retexture Request Missing Value");
			}
		}
	}

	private void ApplyTexture(CreatureBoardAsset asset, GameObject go, Material mat, string source)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)asset != (Object)null && (Object)(object)mat != (Object)null && source != null && source != "")
		{
			if (!originalMaterials.ContainsKey(asset.CreatureId))
			{
				LoggingPlugin.LogDebug("Storing orignal " + asset.Name + " material");
				originalMaterials.Add(asset.CreatureId, mat);
			}
			if (source.EndsWith(".mp4") || source.EndsWith(".mov;") || source.EndsWith(".webm;") || source.EndsWith(".wmv;"))
			{
				ApplyVideo(go, "RETEXTURE_MAT", source);
				return;
			}
			SRFGameObjectExtensions.RemoveComponentIfExists<VideoPlayer>(go);
			IEnumerable<GameObject> enumerable = from v in go.GetComponentsInChildren<VideoPlayer>()
				select ((Component)v).gameObject;
			foreach (GameObject item in enumerable)
			{
				SRFGameObjectExtensions.RemoveComponentIfExists<VideoPlayer>(item);
			}
			LoggingPlugin.LogDebug("Retexturing " + asset.Name + " main texture (" + ((Object)mat).name + ":" + ((Object)mat.mainTexture).name + ") with '" + source + "'");
			mat.mainTexture = (Texture)(object)LoadTextureRGBA32(File.Find(source, (CacheType)999).First());
		}
		else
		{
			LoggingPlugin.LogWarning("Apply Texture Has Null Asset, Null Mateiral, Or Null Source");
		}
	}

	private void RestoreTexture(CreatureBoardAsset asset, GameObject go, Material mat)
	{
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		if (((Object)(object)asset != (Object)null) & ((Object)(object)mat != (Object)null))
		{
			SRFGameObjectExtensions.RemoveComponentIfExists<VideoPlayer>(go);
			IEnumerable<GameObject> enumerable = from v in go.GetComponentsInChildren<VideoPlayer>()
				select ((Component)v).gameObject;
			foreach (GameObject item in enumerable)
			{
				SRFGameObjectExtensions.RemoveComponentIfExists<VideoPlayer>(item);
			}
			LoggingPlugin.LogDebug("Restoring " + asset.Name + " original material");
			mat = originalMaterials[asset.CreatureId];
			LoggingPlugin.LogDebug("Removing stored material for " + asset.Name);
			originalMaterials.Remove(asset.CreatureId);
		}
		else
		{
			LoggingPlugin.LogWarning("Restore Texture Has Null Asset, or Null Mateiral");
		}
	}

	private Material FindMaterial(GameObject asset, string name, bool useDefault = true)
	{
		List<Renderer> list = new List<Renderer>();
		MeshRenderer[] componentsInChildren = asset.GetComponentsInChildren<MeshRenderer>();
		foreach (MeshRenderer val in componentsInChildren)
		{
			LoggingPlugin.LogDebug("Adding MeshRenderer " + ((Object)val).name);
			list.Add((Renderer)(object)val);
		}
		SkinnedMeshRenderer[] componentsInChildren2 = asset.GetComponentsInChildren<SkinnedMeshRenderer>();
		foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
		{
			LoggingPlugin.LogDebug("Adding SkinnedMeshRenderer " + ((Object)val2).name);
			list.Add((Renderer)(object)val2);
		}
		foreach (Renderer item in list)
		{
			Material[] materials = item.materials;
			foreach (Material val3 in materials)
			{
				LoggingPlugin.LogDebug("Looking At Material " + ((Object)item).name + "." + ((Object)val3).name);
				if (((Object)val3).name.Contains(name))
				{
					LoggingPlugin.LogDebug("Retexture Plug-In Found " + ((Object)item).name + "." + ((Object)val3).name);
					return val3;
				}
			}
		}
		LoggingPlugin.LogDebug("Using Default/Null");
		return useDefault ? list[0].material : null;
	}

	private void ApplyVideo(GameObject asset, string name, string source)
	{
		if ((Object)(object)asset != (Object)null && name != null && name != "" && source != null && source != "")
		{
			List<Renderer> list = new List<Renderer>();
			MeshRenderer[] componentsInChildren = asset.GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				LoggingPlugin.LogDebug("Adding MeshRenderer " + ((Object)val).name);
				list.Add((Renderer)(object)val);
			}
			SkinnedMeshRenderer[] componentsInChildren2 = asset.GetComponentsInChildren<SkinnedMeshRenderer>();
			foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
			{
				LoggingPlugin.LogDebug("Adding SkinnedMeshRenderer " + ((Object)val2).name);
				list.Add((Renderer)(object)val2);
			}
			{
				VideoPlayer val4 = default(VideoPlayer);
				foreach (Renderer item in list)
				{
					Material[] materials = item.materials;
					foreach (Material val3 in materials)
					{
						LoggingPlugin.LogDebug("Looking At Material " + ((Object)item).name + "." + ((Object)val3).name);
						if (((Object)val3).name.Contains(name))
						{
							LoggingPlugin.LogDebug("Found " + ((Object)item).name + "." + ((Object)val3).name);
							GameObject gameObject = ((Component)item).gameObject;
							if (!gameObject.TryGetComponent<VideoPlayer>(ref val4))
							{
								val4 = gameObject.AddComponent<VideoPlayer>();
							}
							val4.playOnAwake = true;
							val4.source = (VideoSource)1;
							if (!source.StartsWith("http"))
							{
								source = "file://" + source;
							}
							val4.url = source;
							val4.isLooping = true;
							return;
						}
					}
				}
				return;
			}
		}
		LoggingPlugin.LogWarning("Apply Vide Has Null Asset, Null Name, or Null Source");
	}

	private static string Lineage(GameObject gameObject)
	{
		string text = ((Object)gameObject).name;
		while ((Object)(object)gameObject.transform.parent != (Object)null)
		{
			gameObject = ((Component)gameObject.transform.parent).gameObject;
			text = ((Object)gameObject).name + "." + text;
		}
		return text;
	}

	public static bool StartsWithGuid(string input)
	{
		if (string.IsNullOrWhiteSpace(input))
		{
			return false;
		}
		int num = Math.Min(input.Length, 38);
		for (int i = 32; i <= num; i++)
		{
			if (System.Guid.TryParse(input.Substring(0, i), out var _))
			{
				return true;
			}
		}
		return false;
	}

	public static Texture2D LoadTextureRGBA32(string filePath)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		if (!File.Exists(filePath))
		{
			Debug.LogError((object)("Texture file not found: " + filePath));
			return null;
		}
		byte[] array = File.ReadAllBytes(filePath);
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false);
		if (!ImageConversion.LoadImage(val, array, false))
		{
			Debug.LogError((object)("Failed to load image: " + filePath));
			return null;
		}
		((Texture)val).wrapMode = (TextureWrapMode)1;
		((Texture)val).filterMode = (FilterMode)1;
		val.Apply();
		return val;
	}
}