Decompiled source of AnimatedCybergrindTextures v1.0.0

plugins/AnimatedCybergrindTextures/AnimatedCybergrindTextures.dll

Decompiled 2 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using AnimatedCybergrindTextures.Components;
using AnimatedCybergrindTextures.Utils;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AnimatedCybergrindTextures")]
[assembly: AssemblyDescription("ULTRAKILL mod for using videos as Cybergrind textures")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AnimatedCybergrindTextures")]
[assembly: AssemblyCopyright("Copyright © 2024 Flazhik")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5C47D081-54C6-459C-AAE5-883E54B2C7F1")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace AnimatedCybergrindTextures
{
	[BepInProcess("ULTRAKILL.exe")]
	[BepInPlugin("dev.flazhik.animatedcgtextures", "AnimatedCybergrindTextures", "1.0.0")]
	public class AnimatedCybergrindTextures : BaseUnityPlugin
	{
		private static Harmony _harmony;

		private void Awake()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			MonoSingleton<AssetsManager>.Instance.LoadAssets();
			MonoSingleton<AssetsManager>.Instance.RegisterAssets();
			_harmony = new Harmony("dev.flazhik.animatedcgtextures");
			_harmony.PatchAll();
		}
	}
	[ConfigureSingleton(/*Could not decode attribute arguments.*/)]
	public class AssetsManager : MonoSingleton<AssetsManager>
	{
		private const BindingFlags Flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly Dictionary<string, Object> Prefabs = new Dictionary<string, Object>();

		private AssetBundle _bundle;

		public void LoadAssets()
		{
			_bundle = AssetBundle.LoadFromMemory(Resources.AnimatedCybergrindTextures);
		}

		public void RegisterAssets()
		{
			string[] allAssetNames = _bundle.GetAllAssetNames();
			foreach (string text in allAssetNames)
			{
				Prefabs.Add(text, _bundle.LoadAsset<Object>(text));
			}
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				CheckType(types[i]);
			}
		}

		private static void CheckType(IReflect type)
		{
			type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).ToList().ForEach(ProcessField);
		}

		private static void ProcessField(FieldInfo field)
		{
			//IL_004a: 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)
			if (!field.FieldType.IsArray && field.IsStatic)
			{
				ExternalAsset customAttribute = field.GetCustomAttribute<ExternalAsset>();
				UltrakillAsset customAttribute2 = field.GetCustomAttribute<UltrakillAsset>();
				if (customAttribute != null)
				{
					field.SetValue(null, Prefabs[customAttribute.Path]);
				}
				else if (customAttribute2 != null)
				{
					field.SetValue(null, Addressables.LoadAssetAsync<GameObject>((object)customAttribute2.Path).WaitForCompletion());
				}
			}
		}
	}
	public static class Configuration
	{
		private static readonly ConfigFile Config = new ConfigFile(Path.Combine(Paths.ConfigPath, "AnimatedCybergrindTextures", "config.cfg"), true);

		public static readonly ConfigEntry<float> PreviewLoadingTimeout = Config.Bind<float>("VideoPlayer", "PreviewTimeout", 5f, "Timeout for a video preview loading attempt in seconds");

		public static readonly ConfigEntry<int> SkyboxWidth = Config.Bind<int>("Skybox", "Width", 1920, "Width of a skybox texture");

		public static readonly ConfigEntry<int> SkyboxHeight = Config.Bind<int>("Skybox", "Height", 960, "Height of a skybox texture");

		public static readonly ConfigEntry<int> SkyboxColorDepth = Config.Bind<int>("Skybox", "Depth", 24, "Color depth used by skybox video player");

		public static readonly ConfigEntry<int> TileSize = Config.Bind<int>("Tiles", "Size", 100, "Width and height of a texture of a single tile on the grid");

		public static readonly ConfigEntry<int> TileColorDepth = Config.Bind<int>("Tiles", "Depth", 24, "Color depth used by tiles video player");
	}
	internal static class PluginInfo
	{
		public const string GUID = "dev.flazhik.animatedcgtextures";

		public const string NAME = "AnimatedCybergrindTextures";

		public const string VERSION = "1.0.0";
	}
	[AttributeUsage(AttributeTargets.Field)]
	public class ExternalAsset : Attribute
	{
		public string Path { get; }

		public ExternalAsset(string path = "")
		{
			Path = path;
		}
	}
	[AttributeUsage(AttributeTargets.Field)]
	public class UltrakillAsset : Attribute
	{
		public string Path { get; }

		public UltrakillAsset(string path = "")
		{
			Path = path;
		}
	}
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("AnimatedCybergrindTextures.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] AnimatedCybergrindTextures => (byte[])ResourceManager.GetObject("AnimatedCybergrindTextures", resourceCulture);

		internal Resources()
		{
		}
	}
}
namespace AnimatedCybergrindTextures.Utils
{
	public static class GenericUtils
	{
		public const string CustomGridKey = "cyberGrind.customGrid";

		public const string CustomSkyboxKey = "cyberGrind.customSkybox";

		private static readonly List<string> VideoExtensions = new List<string>
		{
			".asf", ".avi", ".dv", ".m4v", ".mov", ".mp4", ".mpg", ".mpeg", ".ogv", ".vp8",
			".webm", ".wmv"
		};

		public static VideoPlayer InitVideoPlayer(Transform parent)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			VideoPlayer obj = Object.Instantiate<GameObject>(new GameObject("AnimatedTexturesPlayer"), parent, true).AddComponent<VideoPlayer>();
			obj.isLooping = true;
			obj.SetDirectAudioMute((ushort)0, true);
			return obj;
		}

		public static bool HasVideoExtension(string key)
		{
			return VideoExtensions.Contains(new FileInfo(key).Extension.ToLower());
		}

		public static string KeyToUrl(string key)
		{
			return "file://" + new FileInfo(key).FullName;
		}
	}
	public static class ReflectionUtils
	{
		private const BindingFlags BindingFlagsFields = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		public static object GetPrivate<T>(T instance, Type classType, string field)
		{
			FieldInfo field2 = classType.GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field2 != null))
			{
				return null;
			}
			return field2.GetValue(instance);
		}
	}
}
namespace AnimatedCybergrindTextures.Patches
{
	[HarmonyPatch(typeof(CustomTextures))]
	public class CustomTexturesPatch
	{
		private const string AdditionalOptions = "/FirstRoom/Room/CyberGrindSettings/Canvas/CustomTextures/Panel/AdditionalOptions";

		private const string DisableSkyboxRotationKey = "cyberGrind.customSkybox.disableSpin";

		[ExternalAsset("Assets/Textures/animated_icon.png")]
		private static Texture2D _animatedIcon;

		[ExternalAsset("Assets/Elements/SkyboxToggle.prefab")]
		private static GameObject _skyboxToggleTemplate;

		[UltrakillAsset("b433c919446768d4a9e64494c6bfd084")]
		private static GameObject _shopClick;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CustomTextures), "Start")]
		public static bool CustomTextures_Start_Prefix(CustomTextures __instance, Material[] ___gridMaterials, Material ___skyMaterial, OutdoorLightMaster ___olm, GameObject ___itemButtonTemplate, Dictionary<string, Texture2D> ___imageCache)
		{
			GameObject gameObject = ((Component)MonoSingleton<EndlessGrid>.Instance).gameObject;
			AnimatedTexturesManager animatedTexturesManager = default(AnimatedTexturesManager);
			if (gameObject.TryGetComponent<AnimatedTexturesManager>(ref animatedTexturesManager))
			{
				return true;
			}
			animatedTexturesManager = gameObject.AddComponent<AnimatedTexturesManager>();
			AsyncTexturePreviewLoader asyncTexturePreviewLoader = gameObject.AddComponent<AsyncTexturePreviewLoader>();
			animatedTexturesManager.gridMaterials = ___gridMaterials;
			animatedTexturesManager.skyboxMaterial = ___skyMaterial;
			animatedTexturesManager.olm = ___olm;
			asyncTexturePreviewLoader.OriginalCache = ___imageCache;
			AddAnimatedIcon(___itemButtonTemplate);
			animatedTexturesManager.skyboxRotationToggle = AddSkyboxRotationToggle(___olm);
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CustomTextures), "Start")]
		public static void CustomTextures_Start_Postfix(CustomTextures __instance, Material[] ___gridMaterials, Material ___skyMaterial)
		{
			PrefsManager instance = MonoSingleton<PrefsManager>.Instance;
			AnimatedTexturesManager animatedTexturesManager = AnimatedTextures();
			for (int i = 0; i < 3; i++)
			{
				string stringLocal = instance.GetStringLocal(string.Format("{0}_{1}", "cyberGrind.customGrid", i), (string)null);
				if (!string.IsNullOrEmpty(stringLocal))
				{
					animatedTexturesManager.SetGridTexture(stringLocal, i);
				}
			}
			string stringLocal2 = instance.GetStringLocal("cyberGrind.customSkybox", (string)null);
			if (!string.IsNullOrEmpty(stringLocal2))
			{
				animatedTexturesManager.SetSkyboxTexture(stringLocal2);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CustomTextures), "BuildLeaf")]
		public static bool CustomTextures_BuildLeaf_Prefix(CustomTextures __instance, FileInfo file, GameObject ___itemButtonTemplate, Transform ___itemParent, ref Action __result)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			GameObject btn = Object.Instantiate<GameObject>(___itemButtonTemplate, ___itemParent, false);
			((UnityEventBase)btn.GetComponent<Button>().onClick).RemoveAllListeners();
			((UnityEvent)btn.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				__instance.SetTexture(file.FullName);
			});
			btn.SetActive(true);
			if (!GenericUtils.HasVideoExtension(file.FullName))
			{
				foreach (Transform item in btn.transform)
				{
					((Component)item).gameObject.SetActive(false);
				}
			}
			if ((Object)(object)AsyncTextureLoader() != (Object)null)
			{
				AsyncTextureLoader().LoadPreview(file.FullName, btn);
			}
			__result = delegate
			{
				Object.Destroy((Object)(object)btn);
			};
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CustomTextures), "SetTexture")]
		public static bool CustomTextures_SetTexture_Prefix(string key, CustomTextures __instance, bool ___editBase, bool ___editTop, bool ___editTopRow)
		{
			if (!GenericUtils.HasVideoExtension(key))
			{
				return true;
			}
			string editMode = ReflectionUtils.GetPrivate<CustomTextures>(__instance, typeof(CustomTextures), "currentEditMode").ToString();
			AnimatedTextures().SetTexture(key, editMode, ___editBase, ___editTop, ___editTopRow);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CustomTextures), "SetEditMode")]
		public static void CustomTextures_SetEditMode_Postfix(int m, CustomTextures __instance)
		{
			AnimatedTextures().skyboxRotationToggle.SetActive(m == 2);
		}

		private static void AddAnimatedIcon(GameObject template)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Animated Icon");
			val.transform.parent = template.transform;
			Image val2 = val.AddComponent<Image>();
			RectTransform component = val.GetComponent<RectTransform>();
			Sprite sprite = Sprite.Create(_animatedIcon, new Rect(0f, 0f, (float)((Texture)_animatedIcon).width, (float)((Texture)_animatedIcon).height), new Vector2(0.5f, 0.5f), 100f);
			val2.sprite = sprite;
			val.transform.localPosition = new Vector3(15f, 20f, 0f);
			component.sizeDelta = new Vector2(32f, 32f);
			((Transform)component).localScale = Vector2.op_Implicit(new Vector2(1f, 1f));
		}

		private static GameObject AddSkyboxRotationToggle(OutdoorLightMaster olm)
		{
			GameObject obj = Object.Instantiate<GameObject>(_skyboxToggleTemplate, GameObject.Find("/FirstRoom/Room/CyberGrindSettings/Canvas/CustomTextures/Panel/AdditionalOptions").transform);
			obj.AddComponent<HudOpenEffect>();
			obj.SetActive(false);
			bool boolLocal = MonoSingleton<PrefsManager>.Instance.GetBoolLocal("cyberGrind.customSkybox.disableSpin", true);
			olm.dontRotateSkybox = boolLocal;
			Toggle componentInChildren = obj.GetComponentInChildren<Toggle>();
			obj.gameObject.AddComponent<ShopButton>().clickSound = _shopClick;
			componentInChildren.isOn = olm.dontRotateSkybox;
			((UnityEvent<bool>)(object)componentInChildren.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
			{
				Object.Instantiate<GameObject>(_shopClick);
				MonoSingleton<PrefsManager>.Instance.SetBoolLocal("cyberGrind.customSkybox.disableSpin", value);
				olm.dontRotateSkybox = value;
			});
			return obj;
		}

		private static AnimatedTexturesManager AnimatedTextures()
		{
			return ((Component)MonoSingleton<EndlessGrid>.Instance).gameObject.GetComponent<AnimatedTexturesManager>();
		}

		private static AsyncTexturePreviewLoader AsyncTextureLoader()
		{
			return ((Component)MonoSingleton<EndlessGrid>.Instance).gameObject.GetComponent<AsyncTexturePreviewLoader>();
		}
	}
}
namespace AnimatedCybergrindTextures.Components
{
	public class AnimatedTexturesManager : MonoBehaviour
	{
		public Material[] gridMaterials;

		public RenderTexture[] gridTextures;

		public Material skyboxMaterial;

		public RenderTexture skyboxTexture;

		public VideoPlayer[] gridPlayers;

		public VideoPlayer skyboxPlayer;

		public OutdoorLightMaster olm;

		public GameObject skyboxRotationToggle;

		private void Awake()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			gridTextures = (RenderTexture[])(object)new RenderTexture[3];
			gridPlayers = (VideoPlayer[])(object)new VideoPlayer[3];
			skyboxTexture = new RenderTexture(Configuration.SkyboxWidth.Value, Configuration.SkyboxHeight.Value, Configuration.SkyboxColorDepth.Value);
			skyboxPlayer = GenericUtils.InitVideoPlayer(((Component)this).transform);
			skyboxPlayer.targetTexture = skyboxTexture;
			for (int i = 0; i < 3; i++)
			{
				gridTextures[i] = new RenderTexture(Configuration.TileSize.Value, Configuration.TileSize.Value, Configuration.TileColorDepth.Value);
				gridPlayers[i] = GenericUtils.InitVideoPlayer(((Component)this).transform);
				gridPlayers[i].targetTexture = gridTextures[i];
			}
		}

		public void SetTexture(string key, string editMode, bool editBase, bool editTop, bool editTopRow)
		{
			if (!GenericUtils.HasVideoExtension(key))
			{
				return;
			}
			if (!(editMode == "Grid"))
			{
				if (editMode == "Skybox")
				{
					SetSkyboxTexture(key);
				}
				return;
			}
			for (int i = 0; i < gridMaterials.Length; i++)
			{
				if (gridPlayers[i].url != null)
				{
					gridPlayers[i].Stop();
				}
				if ((editBase || i != 0) && (editTop || i != 1) && (editTopRow || i != 2))
				{
					MonoSingleton<PrefsManager>.Instance.SetStringLocal(string.Format("{0}_{1}", "cyberGrind.customGrid", i), key);
					gridPlayers[i].url = GenericUtils.KeyToUrl(key);
					gridPlayers[i].Prepare();
					gridPlayers[i].frame = 0L;
					gridMaterials[i].mainTexture = (Texture)(object)gridTextures[i];
				}
				if (gridPlayers[i].url != null)
				{
					gridPlayers[i].Play();
				}
			}
		}

		public void SetGridTexture(string key, int index)
		{
			if (GenericUtils.HasVideoExtension(key))
			{
				if (gridPlayers[index].url != null)
				{
					gridPlayers[index].Stop();
				}
				gridPlayers[index].url = GenericUtils.KeyToUrl(key);
				gridPlayers[index].Prepare();
				gridPlayers[index].frame = 0L;
				gridMaterials[index].mainTexture = (Texture)(object)gridTextures[index];
				if (gridPlayers[index].url != null)
				{
					gridPlayers[index].Play();
				}
			}
		}

		public void SetSkyboxTexture(string key)
		{
			if (GenericUtils.HasVideoExtension(key))
			{
				if ((Object)(object)skyboxPlayer != (Object)null)
				{
					skyboxPlayer.Stop();
				}
				skyboxPlayer.url = GenericUtils.KeyToUrl(key);
				skyboxPlayer.Prepare();
				skyboxPlayer.frame = 0L;
				skyboxMaterial.mainTexture = (Texture)(object)skyboxTexture;
				skyboxPlayer.Play();
				olm.UpdateSkyboxMaterial();
				MonoSingleton<PrefsManager>.Instance.SetStringLocal("cyberGrind.customSkybox", key);
			}
		}
	}
	public class AsyncTexturePreviewLoader : MonoBehaviour
	{
		public Dictionary<string, Texture2D> OriginalCache;

		public void LoadPreview(string key, GameObject button)
		{
			((MonoBehaviour)this).StartCoroutine(GenericUtils.HasVideoExtension(key) ? LoadVideoPreview(key, Callback) : LoadTexture(key, Callback));
			void Callback(Texture2D tex)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)tex == (Object)null))
				{
					Sprite val = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f), 100f);
					((Texture)val.texture).filterMode = (FilterMode)0;
					button.GetComponent<Image>().sprite = val;
				}
			}
		}

		private IEnumerator LoadTexture(string key, Action<Texture2D> callback)
		{
			if (OriginalCache.TryGetValue(key, out var value))
			{
				callback(value);
				yield break;
			}
			UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(GenericUtils.KeyToUrl(key));
			try
			{
				yield return uwr.SendWebRequest();
				if (uwr.error != null)
				{
					Debug.Log((object)uwr.error);
					yield break;
				}
				Texture2D content = DownloadHandlerTexture.GetContent(uwr);
				((Texture)content).filterMode = (FilterMode)0;
				OriginalCache[key] = content;
				callback(content);
			}
			finally
			{
				((IDisposable)uwr)?.Dispose();
			}
		}

		private IEnumerator LoadVideoPreview(string key, Action<Texture2D> callback)
		{
			float timeout = Configuration.PreviewLoadingTimeout.Value;
			VideoPlayer previewPlayer = GenericUtils.InitVideoPlayer(((Component)this).transform);
			if (previewPlayer.url != null)
			{
				previewPlayer.Stop();
			}
			previewPlayer.url = GenericUtils.KeyToUrl(key);
			previewPlayer.Prepare();
			while (!previewPlayer.isPrepared)
			{
				yield return null;
				timeout -= Time.deltaTime;
				if (timeout <= 0f)
				{
					break;
				}
			}
			if ((Object)(object)previewPlayer != (Object)null && !previewPlayer.isPrepared)
			{
				Object.Destroy((Object)(object)((Component)previewPlayer).gameObject);
				yield break;
			}
			Texture texture2 = previewPlayer.texture;
			int width = texture2.width;
			int height = texture2.height;
			Texture2D texture = new Texture2D(width, height, (TextureFormat)4, false);
			RenderTexture renderTexture = new RenderTexture(width, height, 24);
			previewPlayer.targetTexture = renderTexture;
			previewPlayer.sendFrameReadyEvents = true;
			previewPlayer.frame = (int)previewPlayer.frameCount / 2;
			previewPlayer.Play();
			previewPlayer.Pause();
			previewPlayer.frameReady += (FrameReadyEventHandler)delegate
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				RenderTexture.active = renderTexture;
				texture.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0);
				texture.Apply();
				RenderTexture.active = null;
				Object.Destroy((Object)(object)((Component)previewPlayer).gameObject);
				callback(texture);
			};
		}
	}
}