Decompiled source of VR Shader Fix v0.1.0

plugins/VRShaderFix.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using VRShaderFix;
using VRShaderFix.utils;

[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("VRShaderFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Replaces All Materials to use VR Compatiable Shader Version")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("VRShaderFix")]
[assembly: AssemblyTitle("VRShaderFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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;
		}
	}
}
public class AssetBundleScanner
{
	public class ShaderInfo
	{
		public string Name;

		public Shader Shader;

		public string BundleName;
	}

	public List<ShaderInfo> LoadedShaders = new List<ShaderInfo>();

	private readonly HashSet<string> ShaderNames = new HashSet<string>();

	private readonly ManualLogSource Logger;

	private readonly MonoBehaviour CoroutineHost;

	private readonly Queue<(AssetBundle bundle, string name)> SceneBundleQueue = new Queue<(AssetBundle, string)>();

	private bool SceneCoroutineRunning;

	public AssetBundleScanner(ManualLogSource logger, MonoBehaviour host)
	{
		Logger = logger;
		CoroutineHost = host;
	}

	public void RunScan()
	{
	}
}
public class ShaderFix : MonoBehaviour
{
	private static readonly Dictionary<string, Shader> AutoDetectedHDRPShaders = new Dictionary<string, Shader>(StringComparer.OrdinalIgnoreCase);

	public static Dictionary<string, Shader> MissingShaders = new Dictionary<string, Shader>(StringComparer.OrdinalIgnoreCase);

	public Dictionary<string, Shader> CustomShaders = new Dictionary<string, Shader>(StringComparer.OrdinalIgnoreCase);

	private string ShaderPath;

	private Dictionary<int, string> BaseGameShaders = new Dictionary<int, string>();

	public HashSet<string> CachedBlacklist { get; set; }

	public void StartShaderFix()
	{
		((MonoBehaviour)this).StartCoroutine(CacheBaseGameCustomShaders());
		((MonoBehaviour)this).StartCoroutine(DelayedShaderFix());
		if (Plugin.VRConfig.enableDebug.Value)
		{
			DebugFindDups();
		}
	}

	public void AddMissingShader(string Name, Shader shader)
	{
		if (!CustomShaders.ContainsKey(Name) && !MissingShaders.ContainsKey(Name))
		{
			MissingShaders.Add(Name, shader);
		}
	}

	private void DebugFindDups()
	{
		foreach (string item in CustomShaders.Keys.Intersect<string>(AutoDetectedHDRPShaders.Keys, StringComparer.OrdinalIgnoreCase))
		{
			Shader val = AutoDetectedHDRPShaders[item];
			Shader val2 = CustomShaders[item];
			Plugin.Logger.LogWarning((object)"--------------^^^^^^--------------");
			Plugin.Logger.LogError((object)("Duplicate Shader Key: " + item + "\n" + $"  BaseGame InstanceID: {((Object)val).GetInstanceID()}\n" + $"  Custom InstanceID:   {((Object)val2).GetInstanceID()}\n"));
		}
	}

	private IEnumerator CacheBaseGameCustomShaders()
	{
		Shader[] array = Resources.FindObjectsOfTypeAll<Shader>();
		Shader[] array2 = array;
		foreach (Shader shader in array2)
		{
			yield return (object)new WaitForEndOfFrame();
			if (!((Object)(object)shader == (Object)null))
			{
				string name = ((Object)shader).name;
				if (BaseGameShaders.TryGetValue(((Object)shader).GetInstanceID(), out var value) && value == name)
				{
					CustomShaders[name] = shader;
				}
			}
		}
		yield return (object)new WaitForEndOfFrame();
	}

	private IEnumerator DelayedShaderFix()
	{
		yield return (object)new WaitForSeconds(2f);
		Material[] array = Resources.FindObjectsOfTypeAll<Material>();
		foreach (Material val in array)
		{
			ShaderFixer.ReplaceShader(val, ResolveShader(((Object)val.shader).name));
		}
		ReplaceTerrainShaders(Resources.FindObjectsOfTypeAll<Terrain>());
	}

	private void ReplaceTerrainShaders(IEnumerable<Terrain> terrains)
	{
		foreach (Terrain terrain in terrains)
		{
			if ((Object)(object)terrain == (Object)null)
			{
				Plugin.Logger.LogError((object)"Terrain is NULL");
				continue;
			}
			Material materialTemplate = terrain.materialTemplate;
			if ((Object)(object)materialTemplate == (Object)null)
			{
				continue;
			}
			Shader shader = materialTemplate.shader;
			if (!((Object)(object)shader == (Object)null))
			{
				Shader val = ResolveShader(((Object)shader).name);
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Logger.LogError((object)("ResolveShader FAILED for terrain '" + ((Object)terrain).name + "' shader '" + ((Object)shader).name + "'"));
					continue;
				}
				Plugin.Logger.LogInfo((object)("REPLACE TERRAIN SHADER: " + ((Object)terrain).name + " " + ((Object)shader).name + " → " + ((Object)val).name));
				ShaderFixer.ReplaceShader(materialTemplate, val);
				terrain.terrainData.terrainLayers = terrain.terrainData.terrainLayers;
				terrain.terrainData.RefreshPrototypes();
				terrain.Flush();
				Plugin.Logger.LogInfo((object)("DONE: Terrain " + ((Object)terrain).name + " shader replaced and marked"));
			}
		}
	}

	public Shader ResolveShader(string shaderName)
	{
		if (CustomShaders.TryGetValue(shaderName, out var value))
		{
			return value;
		}
		if (AutoDetectedHDRPShaders.TryGetValue(shaderName, out var value2))
		{
			if (Plugin.VRConfig.enableDebug.Value)
			{
				Plugin.Logger.LogWarning((object)("Game shader used: " + ((Object)value2).name + " (Auto Detected Shader not guaranteed to work in VR)"));
			}
			return value2;
		}
		if (!MissingShaders.ContainsKey(shaderName))
		{
			MissingShaders.Add(shaderName, Shader.Find(shaderName));
		}
		return ShaderFixer.FindClosestShader(shaderName, CustomShaders) ?? ShaderFixer.FindClosestShader(shaderName, AutoDetectedHDRPShaders);
	}

	public bool IsBaseGameShader(Shader shader)
	{
		if (AutoDetectedHDRPShaders.TryGetValue(((Object)shader).name, out var value) && ((Object)value).GetInstanceID() == ((Object)shader).GetInstanceID())
		{
			return true;
		}
		return false;
	}

	public static void LogMissingShaders()
	{
		if (!Plugin.VRConfig.enableDebug.Value)
		{
			return;
		}
		foreach (KeyValuePair<string, Shader> missingShader in MissingShaders)
		{
			Plugin.Logger.LogWarning((object)"---------Missing---------");
			Plugin.Logger.LogError((object)("Missing VR Variant for Shader: " + ((Object)missingShader.Value).name));
		}
	}

	public void AddCustomShaderSafe(Shader shader)
	{
		if (CustomShaders.ContainsKey(((Object)shader).name))
		{
			Plugin.Logger.LogInfo((object)(((Object)shader).name + " wasn't added as already in custom list"));
		}
		else
		{
			CustomShaders.Add(((Object)shader).name, shader);
		}
	}

	public void CacheBaseGameShaders()
	{
		Plugin.Logger.LogInfo((object)"Scanning for base‑game shaders...");
		ShaderPath = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location), Application.productName + ".VRShaders");
		if (File.Exists(ShaderPath))
		{
			string[] array = File.ReadAllLines(ShaderPath);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(':');
				int.TryParse(array2[1], out var result);
				BaseGameShaders.Add(result, array2[0]);
			}
		}
		Shader[] array3 = Resources.FindObjectsOfTypeAll<Shader>();
		foreach (Shader val in array3)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			string name = ((Object)val).name;
			if (BaseGameShaders.TryGetValue(((Object)val).GetInstanceID(), out var value) && value == name)
			{
				CustomShaders[name] = val;
			}
			name.StartsWith("HDRP/", StringComparison.OrdinalIgnoreCase);
			name.StartsWith("Shader Graphs/", StringComparison.OrdinalIgnoreCase);
			if (name.StartsWith("HIDDEN", StringComparison.OrdinalIgnoreCase))
			{
				continue;
			}
			int instanceID = ((Object)val).GetInstanceID();
			if (instanceID <= 0)
			{
				continue;
			}
			if (!AutoDetectedHDRPShaders.TryGetValue(name, out var value2))
			{
				AutoDetectedHDRPShaders[name] = val;
				Plugin.Logger.LogInfo((object)$"Cached Auto Detected shader: {name} (ID {instanceID})");
				continue;
			}
			int instanceID2 = ((Object)value2).GetInstanceID();
			if (instanceID2 <= 0 || instanceID < instanceID2)
			{
				AutoDetectedHDRPShaders[name] = val;
				Plugin.Logger.LogInfo((object)$"Updated Auto Detected shader: {name} → lower ID {instanceID} (was {instanceID2})");
			}
		}
		Plugin.Logger.LogInfo((object)$"Captured {AutoDetectedHDRPShaders.Count} Auto Detected shaders.");
	}
}
namespace VRShaderFix
{
	[HarmonyPatch]
	internal class Patches
	{
		[HarmonyPatch(typeof(RoundManager), "FinishGeneratingNewLevelClientRpc")]
		[HarmonyPostfix]
		public static void StartVRShaderFixViaPatch()
		{
			Plugin.Logger.LogDebug((object)"VR Shader Fix Applying");
			Plugin.ShaderFixHost.StartShaderFix();
			Plugin.Logger.LogDebug((object)"VR Shader Fix Applied");
		}

		[HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")]
		[HarmonyPostfix]
		public static void StartVRShaderFixViaPatchBackup2()
		{
			Plugin.Logger.LogDebug((object)"VR Shader Fix Backup Call");
			Plugin.ShaderFixHost.StartShaderFix();
			Plugin.Logger.LogDebug((object)"VR Shader Fix Backup Call End");
		}
	}
	[BepInPlugin("TKronix.VRShaderFix", "VRShaderFix", "0.1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private const string GUID = "TKronix.VRShaderFix";

		private const string NAME = "VRShaderFix";

		private const string VERSION = "0.1.0.0";

		private static InputAction hotkey = null;

		private static InputAction hotkey2 = null;

		private static InputAction hotkey3 = null;

		private static InputAction hotkey4 = null;

		private static int moonID = 13;

		public static Plugin Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; } = null;

		public static ShaderFix ShaderFixHost { get; private set; } = null;

		internal static VRSFConfig VRConfig { get; private set; } = null;

		private void Awake()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Logger.LogInfo((object)"Plugin loading");
			VRConfig = new VRSFConfig(((BaseUnityPlugin)this).Config);
			hotkey = new InputAction("RunVRShaderFix", (InputActionType)1, "<Keyboard>/f1", (string)null, (string)null, (string)null);
			hotkey2 = new InputAction("RunVRShaderFix2", (InputActionType)1, "<Keyboard>/f2", (string)null, (string)null, (string)null);
			hotkey3 = new InputAction("RunVRShaderFix2", (InputActionType)1, "<Keyboard>/f3", (string)null, (string)null, (string)null);
			hotkey4 = new InputAction("RunVRShaderFix2", (InputActionType)1, "<Keyboard>/f4", (string)null, (string)null, (string)null);
			hotkey.performed += delegate
			{
				ShaderFixHost.StartShaderFix();
			};
			hotkey2.performed += delegate
			{
				Hotkey2();
			};
			hotkey3.performed += delegate
			{
				Hotkey3();
			};
			hotkey4.performed += delegate
			{
				Hotkey4();
			};
			DisableHotkeys();
			if (VRConfig.enableDebug.Value)
			{
				hotkey.Enable();
				hotkey2.Enable();
				hotkey3.Enable();
				hotkey4.Enable();
			}
			SceneManager.sceneLoaded += InitalizeVRShaderFix;
			if (VRConfig.enableHarmonyPatches.Value)
			{
				new Harmony("TKronix.VRShaderFix").PatchAll(typeof(Patches));
				Logger.LogInfo((object)"Plugin Harmony Patches Applied!");
			}
			Logger.LogInfo((object)"Plugin loaded!");
		}

		private void InitalizeVRShaderFix(Scene scene, LoadSceneMode mode)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			if (!((Scene)(ref scene)).name.Equals("MainMenu", StringComparison.OrdinalIgnoreCase))
			{
				return;
			}
			GameObject val = new GameObject("VRShaderFixHost");
			Object.DontDestroyOnLoad((Object)val);
			ShaderFixHost = val.AddComponent<ShaderFix>();
			ShaderFixHost.CacheBaseGameShaders();
			AssetBundle val2 = LoadAssetBundle("vrmaterials");
			Material[] array = val2.LoadAllAssets<Material>();
			Shader[] array2 = val2.LoadAllAssets<Shader>();
			Material[] array3 = array;
			foreach (Material val3 in array3)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					Logger.LogInfo((object)("Loaded Material: " + ((Object)val3).name));
					ShaderFixHost.AddCustomShaderSafe(val3.shader);
				}
			}
			if (array2 != null)
			{
				Shader[] array4 = array2;
				foreach (Shader val4 in array4)
				{
					Logger.LogError((object)(((Object)val4).name + " has been loaded"));
					ShaderFixHost.AddCustomShaderSafe(val4);
				}
			}
			val2.Unload(false);
			array = null;
			val2 = null;
			SceneManager.sceneLoaded -= InitalizeVRShaderFix;
			SceneManager.sceneLoaded += ApplyVRFixOnSceneLoad;
			ShaderFixHost.StartShaderFix();
		}

		private void ApplyVRFixOnSceneLoad(Scene scene, LoadSceneMode mode)
		{
			ShaderFixHost.StartShaderFix();
		}

		private static string Center(string text, int totalWidth)
		{
			int num = totalWidth - text.Length;
			int num2 = num / 2;
			int count = num - num2;
			return new string(' ', num2) + text + new string(' ', count);
		}

		private AssetBundle LoadAssetBundle(string AssetBundle)
		{
			return AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), AssetBundle));
		}

		private static void DisableHotkeys()
		{
			hotkey.Disable();
			hotkey2.Disable();
			hotkey3.Disable();
		}

		private static void Hotkey2()
		{
			//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_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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			Logger.LogWarning((object)$"Currently Loaded Scenes Count: {SceneManager.sceneCount}");
			Scene val;
			for (int i = 0; i < SceneManager.sceneCount; i++)
			{
				ManualLogSource logger = Logger;
				object arg = i;
				val = SceneManager.GetSceneAt(i);
				logger.LogError((object)$"{arg}: {((Scene)(ref val)).name}");
			}
			QuickMenuManager val2 = Object.FindObjectOfType<QuickMenuManager>();
			if (Object.op_Implicit((Object)(object)val2) && val2.isMenuOpen)
			{
				Logger.LogInfo((object)"Pause Menu Closing");
				val2.CloseQuickMenu();
				Logger.LogInfo((object)"Pause Menu Closed");
				FlipOcclusionCulling();
				return;
			}
			val = SceneManager.GetActiveScene();
			if (!((Scene)(ref val)).name.Equals("InitSceneLaunchOptions"))
			{
				val = SceneManager.GetActiveScene();
				if (!((Scene)(ref val)).name.Equals("LCVR Init Scene"))
				{
					val = SceneManager.GetActiveScene();
					if (((Scene)(ref val)).name.Equals("MainMenu"))
					{
						Object.FindObjectOfType<MenuManager>().StartHosting();
						return;
					}
					val = SceneManager.GetActiveScene();
					if (((Scene)(ref val)).name.Equals("SampleSceneRelay") && StartOfRound.Instance.currentLevelID != moonID)
					{
						Random random = new Random();
						int num = StartOfRound.Instance.levels.Count() - 1;
						if (moonID < num)
						{
							StartOfRound.Instance.ChangeLevel(moonID);
						}
						else
						{
							StartOfRound.Instance.ChangeLevel(random.Next(num));
						}
						return;
					}
					val = SceneManager.GetActiveScene();
					if (((Scene)(ref val)).name.Equals("SampleSceneRelay") && SceneManager.sceneCount == 1)
					{
						Object.FindObjectOfType<StartMatchLever>().StartGame();
						return;
					}
					val = SceneManager.GetActiveScene();
					if (((Scene)(ref val)).name.Equals("SampleSceneRelay") && SceneManager.sceneCount > 1)
					{
						Object.FindObjectOfType<QuickMenuManager>().LeaveGameConfirm();
						string text = "Left Planet Name: ID";
						string text2 = $"{StartOfRound.Instance.currentLevel.PlanetName}: {StartOfRound.Instance.currentLevelID}";
						int num2 = Mathf.Max(text.Length, text2.Length) + 6;
						string text3 = "╔" + new string('═', num2) + "╗";
						string text4 = "║" + Center(text, num2) + "║";
						string text5 = "║" + Center(text2, num2) + "║";
						string text6 = "╚" + new string('═', num2) + "╝";
						Logger.LogInfo((object)text3);
						Logger.LogInfo((object)text4);
						Logger.LogInfo((object)text5);
						Logger.LogInfo((object)text6);
						moonID++;
					}
					return;
				}
			}
			Object.FindObjectOfType<PreInitSceneScript>().ChooseLaunchOption(false);
		}

		private static void Hotkey3()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			QuickMenuManager val = Object.FindObjectOfType<QuickMenuManager>();
			if (Object.op_Implicit((Object)(object)val) && val.isMenuOpen)
			{
				Logger.LogInfo((object)"Pause Menu Closing");
				val.CloseQuickMenu();
				Logger.LogInfo((object)"Pause Menu Closed");
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name.Equals("InitSceneLaunchOptions"))
			{
				Object.FindObjectOfType<PreInitSceneScript>().ChooseLaunchOption(false);
				return;
			}
			activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name.Equals("MainMenu"))
			{
				Object.FindObjectOfType<MenuManager>().StartAClient();
			}
		}

		private static void Hotkey4()
		{
			new AssetBundleScanner(Logger, (MonoBehaviour)(object)ShaderFixHost).RunScan();
			RoundManager.Instance.FinishGeneratingLevel();
		}

		public static void FlipOcclusionCulling()
		{
			AdjacentRoomCullingModified occlusionCuller = StartOfRound.Instance.occlusionCuller;
			if ((Object)(object)occlusionCuller == (Object)null)
			{
				Logger.LogDebug((object)"Occlusion culler not found.");
				return;
			}
			bool enabled = ((Behaviour)occlusionCuller).enabled;
			bool flag = (((Behaviour)occlusionCuller).enabled = !enabled);
			Logger.LogDebug((object)$"Occlusion culling flipped: {enabled} → {flag}");
		}
	}
	internal class VRSFConfig
	{
		public readonly ConfigEntry<bool> enableHarmonyPatches;

		public readonly ConfigEntry<bool> enableDebug;

		public VRSFConfig(ConfigFile cfg)
		{
			enableHarmonyPatches = cfg.Bind<bool>("HarmonyPatches", "EnableHarmonyPatches", true, "Enable or disable the Harmony Patches");
			enableDebug = cfg.Bind<bool>("Development", "EnableDevelopmentFeatures", false, "Enable or disable Dvelopment features \n(Ignore this its for Development Purposes Only nothing useful for Gameplay)");
		}
	}
}
namespace VRShaderFix.utils
{
	public static class ShaderFixer
	{
		private class CachedMaterialProps
		{
			private readonly Dictionary<string, float> floats = new Dictionary<string, float>();

			private readonly Dictionary<string, int> Ints = new Dictionary<string, int>();

			private readonly Dictionary<string, Color> colors = new Dictionary<string, Color>();

			private readonly Dictionary<string, Vector4> vectors = new Dictionary<string, Vector4>();

			private readonly Dictionary<string, Texture> textures = new Dictionary<string, Texture>();

			private readonly Dictionary<string, Vector2> offsets = new Dictionary<string, Vector2>();

			private readonly Dictionary<string, Vector2> scales = new Dictionary<string, Vector2>();

			public unsafe CachedMaterialProps(Material mat)
			{
				//IL_0072: 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_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Expected I4, but got Unknown
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d6: 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_011f: Unknown result type (might be due to invalid IL or missing references)
				Shader shader = mat.shader;
				int propertyCount = shader.GetPropertyCount();
				for (int i = 0; i < propertyCount; i++)
				{
					string propertyName = shader.GetPropertyName(i);
					ShaderPropertyType propertyType = shader.GetPropertyType(i);
					switch ((int)propertyType)
					{
					case 2:
					case 3:
						floats[propertyName] = mat.GetFloat(propertyName);
						break;
					case 0:
						colors[propertyName] = mat.GetColor(propertyName);
						break;
					case 1:
						vectors[propertyName] = mat.GetVector(propertyName);
						break;
					case 4:
					{
						Texture texture = mat.GetTexture(propertyName);
						textures[propertyName] = texture;
						if ((Object)(object)texture != (Object)null)
						{
							offsets[propertyName] = mat.GetTextureOffset(propertyName);
							scales[propertyName] = mat.GetTextureScale(propertyName);
						}
						break;
					}
					case 5:
						Ints[propertyName] = mat.GetInt(propertyName);
						break;
					default:
						Plugin.Logger.LogWarning((object)("Missing PropertyType Support: " + ((object)(*(ShaderPropertyType*)(&propertyType))/*cast due to .constrained prefix*/).ToString()));
						break;
					}
				}
			}

			public void ApplyTo(Material mat)
			{
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0157: Unknown result type (might be due to invalid IL or missing references)
				//IL_0176: Unknown result type (might be due to invalid IL or missing references)
				foreach (KeyValuePair<string, float> @float in floats)
				{
					if (mat.HasProperty(@float.Key))
					{
						mat.SetFloat(@float.Key, @float.Value);
					}
				}
				foreach (KeyValuePair<string, Color> color in colors)
				{
					if (mat.HasProperty(color.Key))
					{
						mat.SetColor(color.Key, color.Value);
					}
				}
				foreach (KeyValuePair<string, Vector4> vector in vectors)
				{
					if (mat.HasProperty(vector.Key))
					{
						mat.SetVector(vector.Key, vector.Value);
					}
				}
				foreach (KeyValuePair<string, Texture> texture in textures)
				{
					if (mat.HasProperty(texture.Key))
					{
						mat.SetTexture(texture.Key, texture.Value);
						if ((Object)(object)texture.Value != (Object)null)
						{
							mat.SetTextureOffset(texture.Key, offsets[texture.Key]);
							mat.SetTextureScale(texture.Key, scales[texture.Key]);
						}
					}
				}
				foreach (KeyValuePair<string, int> @int in Ints)
				{
					if (mat.HasProperty(@int.Key))
					{
						mat.SetInt(@int.Key, @int.Value);
					}
				}
			}
		}

		private const string MarkerProp = "_VRShaderFix";

		public static void ReplaceShader(Material mat, Shader newShader)
		{
			if (!((Object)(object)mat == (Object)null) && !((Object)(object)newShader == (Object)null) && !(mat.GetFloat("_VRShaderFix") > 0.5f))
			{
				if ((Object)(object)mat.shader == (Object)(object)newShader)
				{
					mat.SetFloat("_VRShaderFix", 1f);
					return;
				}
				int renderQueue = mat.renderQueue;
				string[] shaderKeywords = mat.shaderKeywords;
				float floatSafe = GetFloatSafe(mat, "_Surface");
				float floatSafe2 = GetFloatSafe(mat, "_BlendMode");
				float floatSafe3 = GetFloatSafe(mat, "_AlphaCutoffEnable");
				float floatSafe4 = GetFloatSafe(mat, "_AlphaCutoff");
				float floatSafe5 = GetFloatSafe(mat, "_ZWrite");
				float floatSafe6 = GetFloatSafe(mat, "_EnableFogOnTransparent");
				CachedMaterialProps cachedMaterialProps = new CachedMaterialProps(mat);
				mat.shader = newShader;
				mat.renderQueue = renderQueue;
				mat.shaderKeywords = shaderKeywords;
				SetFloatIfExists(mat, "_Surface", floatSafe);
				SetFloatIfExists(mat, "_BlendMode", floatSafe2);
				SetFloatIfExists(mat, "_AlphaCutoffEnable", floatSafe3);
				SetFloatIfExists(mat, "_AlphaCutoff", floatSafe4);
				SetFloatIfExists(mat, "_ZWrite", floatSafe5);
				SetFloatIfExists(mat, "_EnableFogOnTransparent", floatSafe6);
				cachedMaterialProps.ApplyTo(mat);
				HDMaterial.ValidateMaterial(mat);
				mat.SetFloat("_VRShaderFix", 1f);
			}
		}

		private static float GetFloatSafe(Material m, string prop)
		{
			if (!m.HasProperty(prop))
			{
				return 0f;
			}
			return m.GetFloat(prop);
		}

		private static void SetFloatIfExists(Material m, string prop, float value)
		{
			if (m.HasProperty(prop))
			{
				m.SetFloat(prop, value);
			}
		}

		public static Shader FindClosestShader(string name, Dictionary<string, Shader> shaders)
		{
			Shader result = null;
			int num = -1;
			foreach (KeyValuePair<string, Shader> shader in shaders)
			{
				string key = shader.Key;
				if ((key.StartsWith(name, StringComparison.OrdinalIgnoreCase) || name.StartsWith(key, StringComparison.OrdinalIgnoreCase)) && key.Length > num)
				{
					num = key.Length;
					result = shader.Value;
				}
			}
			return result;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}