Decompiled source of VR Shader Fix v0.0.2

plugins/VRShaderFix.dll

Decompiled a week 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 LethalLevelLoader;
using LethalLevelLoader.AssetBundles;
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: IgnoresAccessChecksTo("LethalLevelLoader")]
[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]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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;
		}
	}
}
public class ShaderFix : MonoBehaviour
{
	[CompilerGenerated]
	private sealed class <CheckMissingShaders>d__10 : IEnumerator<object>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private object <>2__current;

		public ShaderFix <>4__this;

		private Dictionary<string, List<AssetBundleGroup>>.Enumerator <>7__wrap1;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <CheckMissingShaders>d__10(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			int num = <>1__state;
			if (num == -3 || num == 1)
			{
				try
				{
				}
				finally
				{
					<>m__Finally1();
				}
			}
			<>7__wrap1 = default(Dictionary<string, List<AssetBundleGroup>>.Enumerator);
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Expected O, but got Unknown
			try
			{
				int num = <>1__state;
				ShaderFix shaderFix = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					Dictionary<string, List<AssetBundleGroup>> assetBundleGroupSceneDict = NetworkBundleManager.Instance.assetBundleGroupSceneDict;
					Plugin.Logger.LogError((object)assetBundleGroupSceneDict.Count());
					<>7__wrap1 = assetBundleGroupSceneDict.GetEnumerator();
					<>1__state = -3;
					break;
				}
				case 1:
					<>1__state = -3;
					break;
				}
				if (<>7__wrap1.MoveNext())
				{
					KeyValuePair<string, List<AssetBundleGroup>> current = <>7__wrap1.Current;
					foreach (AssetBundleGroup item in current.Value)
					{
						if (item == null)
						{
							continue;
						}
						foreach (AssetBundleInfo assetBundleInfo in item.assetBundleInfos)
						{
							if (assetBundleInfo == null)
							{
								continue;
							}
							Material[] array = assetBundleInfo.assetBundle.LoadAllAssets<Material>();
							if (array == null)
							{
								Plugin.Logger.LogInfo((object)("Mats null " + assetBundleInfo.AssetBundleFileName));
								continue;
							}
							Material[] array2 = array;
							foreach (Material val in array2)
							{
								if (!((Object)(object)val == (Object)null))
								{
									Shader shader = val.shader;
									if (!shaderFix.CustomShaders.ContainsKey(((Object)shader).name) && !MissingShaders.ContainsKey(((Object)shader).name))
									{
										MissingShaders.Add(((Object)shader).name, shader);
										Plugin.Logger.LogInfo((object)("Mat: " + ((Object)val).name + " " + ((Object)shader).name));
									}
								}
							}
							array = null;
						}
					}
					Plugin.Logger.LogInfo((object)("Done with " + current.Key));
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				}
				<>m__Finally1();
				<>7__wrap1 = default(Dictionary<string, List<AssetBundleGroup>>.Enumerator);
				LogMissingShaders();
				return false;
			}
			catch
			{
				//try-fault
				((IDisposable)this).Dispose();
				throw;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		private void <>m__Finally1()
		{
			<>1__state = -1;
			((IDisposable)<>7__wrap1).Dispose();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <DelayedShaderFix>d__11 : IEnumerator<object>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private object <>2__current;

		public ShaderFix <>4__this;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <DelayedShaderFix>d__11(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			int num = <>1__state;
			ShaderFix shaderFix = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			case 1:
			{
				<>1__state = -1;
				Plugin.Logger.LogDebug((object)"Fixing Shaders");
				shaderFix.ReplaceMaterialsFor<Renderer>((IEnumerable<Renderer>)Resources.FindObjectsOfTypeAll<Renderer>());
				shaderFix.ReplaceMaterialsFor<SkinnedMeshRenderer>((IEnumerable<SkinnedMeshRenderer>)Resources.FindObjectsOfTypeAll<SkinnedMeshRenderer>());
				shaderFix.ReplaceMaterialsFor<ParticleSystemRenderer>((IEnumerable<ParticleSystemRenderer>)VRFixUtils.FindAllInLoadedScenes<ParticleSystemRenderer>(Array.Empty<string>()));
				shaderFix.ReplaceMaterialsFor<MeshRenderer>((IEnumerable<MeshRenderer>)Resources.FindObjectsOfTypeAll<MeshRenderer>());
				DecalProjector[] array = Resources.FindObjectsOfTypeAll<DecalProjector>();
				for (int i = 0; i < array.Length; i++)
				{
					Material material = array[i].material;
					if (!((Object)(object)material == (Object)null) && shaderFix.IsValidOriginal(material))
					{
						Shader val = shaderFix.ResolveShader(((Object)material.shader).name);
						if (!((Object)(object)val == (Object)null))
						{
							material.shader = val;
						}
					}
				}
				shaderFix.ReplaceTerrainMaterials(Resources.FindObjectsOfTypeAll<Terrain>());
				LogMissingShaders();
				return false;
			}
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	private static readonly Dictionary<string, Shader> BaseGameHDRPShaders = 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);

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

	public void StartShaderFix()
	{
		//IL_0016: 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)
		if (Plugin.VRConfig.enableBlacklist.Value)
		{
			for (int i = 0; i < SceneManager.sceneCount; i++)
			{
				Scene sceneAt = SceneManager.GetSceneAt(i);
				if (CachedBlacklist.Contains(((Scene)(ref sceneAt)).name))
				{
					Plugin.Logger.LogWarning((object)("Skipped Applying VR Shader Fix to scene '" + ((Scene)(ref sceneAt)).name + "' because is blacklisted in Config"));
					return;
				}
			}
		}
		((MonoBehaviour)this).StartCoroutine(DelayedShaderFix());
		if (Plugin.VRConfig.enableDebug.Value)
		{
			DebugFindDups();
		}
	}

	private void DebugFindDups()
	{
		foreach (string item in CustomShaders.Keys.Intersect<string>(BaseGameHDRPShaders.Keys, StringComparer.OrdinalIgnoreCase))
		{
			Shader val = BaseGameHDRPShaders[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"));
		}
	}

	public void StartCheckMissingShaders()
	{
		((MonoBehaviour)this).StartCoroutine(CheckMissingShaders());
	}

	[IteratorStateMachine(typeof(<CheckMissingShaders>d__10))]
	public IEnumerator CheckMissingShaders()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <CheckMissingShaders>d__10(0)
		{
			<>4__this = this
		};
	}

	[IteratorStateMachine(typeof(<DelayedShaderFix>d__11))]
	private IEnumerator DelayedShaderFix()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <DelayedShaderFix>d__11(0)
		{
			<>4__this = this
		};
	}

	private void ReplaceTerrainMaterials(IEnumerable<Terrain> terrains)
	{
		Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
		foreach (Terrain terrain in terrains)
		{
			Material materialTemplate = terrain.materialTemplate;
			if (!IsValidOriginal(materialTemplate))
			{
				continue;
			}
			Shader val = ResolveShader(((Object)materialTemplate.shader).name);
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			if (!dictionary.TryGetValue(materialTemplate, out var value))
			{
				value = CreateVRMaterial(materialTemplate, val);
				TerrainData terrainData = terrain.terrainData;
				TerrainLayer[] terrainLayers = terrainData.terrainLayers;
				value.shaderKeywords = materialTemplate.shaderKeywords;
				value.renderQueue = materialTemplate.renderQueue;
				value.SetInt("_LayerCount", terrainLayers.Length);
				for (int i = 0; i < terrainData.alphamapTextures.Length; i++)
				{
					value.SetTexture($"_Control{i}", (Texture)(object)terrainData.alphamapTextures[i]);
				}
				for (int j = 0; j < terrainLayers.Length; j++)
				{
					TerrainLayer val2 = terrainLayers[j];
					value.SetTexture($"_Splat{j}", (Texture)(object)val2.diffuseTexture);
					value.SetTexture($"_Normal{j}", (Texture)(object)val2.normalMapTexture);
					value.SetTexture($"_Mask{j}", (Texture)(object)val2.maskMapTexture);
				}
				dictionary[materialTemplate] = value;
			}
			terrain.materialTemplate = dictionary[materialTemplate];
			terrain.terrainData.terrainLayers = terrain.terrainData.terrainLayers;
			ForceDetailRefresh(terrain);
			terrain.terrainData.RefreshPrototypes();
			terrain.Flush();
		}
	}

	private Shader ResolveShader(string shaderName)
	{
		if (CustomShaders.TryGetValue(shaderName, out var value))
		{
			return value;
		}
		if (BaseGameHDRPShaders.TryGetValue(shaderName, out var value2))
		{
			if (Plugin.VRConfig.enableDebug.Value)
			{
				Plugin.Logger.LogWarning((object)("Game shader used: " + ((Object)value2).name));
			}
			return value2;
		}
		if (!MissingShaders.ContainsKey(shaderName))
		{
			MissingShaders.Add(shaderName, Shader.Find(shaderName));
		}
		return VRFixUtils.FindClosestShader(shaderName, CustomShaders) ?? VRFixUtils.FindClosestShader(shaderName, BaseGameHDRPShaders);
	}

	private Material CreateVRMaterial(Material original, Shader shader)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		Material val = new Material(shader)
		{
			name = ((Object)original).name + "_VR"
		};
		MaterialUtils.CopyMaterialProperties(original, val);
		return val;
	}

	private bool IsValidOriginal(Material mat)
	{
		if ((Object)(object)mat == (Object)null)
		{
			return false;
		}
		string name = ((Object)mat).name;
		int num = name.IndexOf(" (", StringComparison.Ordinal);
		return !((num >= 0) ? name.Substring(0, num) : name).Contains("_VR", StringComparison.OrdinalIgnoreCase);
	}

	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));
		}
	}

	private void ReplaceMaterialsFor<TRenderer>(IEnumerable<TRenderer> renderers) where TRenderer : Renderer
	{
		Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
		foreach (TRenderer renderer in renderers)
		{
			Material[] sharedMaterials = ((Renderer)renderer).sharedMaterials;
			if (sharedMaterials == null)
			{
				continue;
			}
			for (int i = 0; i < sharedMaterials.Length; i++)
			{
				Material val = sharedMaterials[i];
				if (!IsValidOriginal(val))
				{
					continue;
				}
				Shader val2 = ResolveShader(((Object)val.shader).name);
				if (!((Object)(object)val2 == (Object)null))
				{
					if (!dictionary.TryGetValue(val, out var value))
					{
						value = (dictionary[val] = CreateVRMaterial(val, val2));
					}
					sharedMaterials[i] = value;
				}
			}
			((Renderer)renderer).sharedMaterials = sharedMaterials;
			((Renderer)renderer).materials = sharedMaterials;
		}
	}

	public static void ForceDetailRefresh(Terrain terrain)
	{
		TerrainData terrainData = terrain.terrainData;
		typeof(TerrainData).GetMethod("RefreshPrototypes", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(terrainData, null);
		for (int i = 0; i < terrainData.detailPrototypes.Length; i++)
		{
			int[,] detailLayer = terrainData.GetDetailLayer(0, 0, terrainData.detailWidth, terrainData.detailHeight, i);
			terrainData.SetDetailLayer(0, 0, i, detailLayer);
		}
	}

	public void CacheBaseGameShaders()
	{
		Plugin.Logger.LogInfo((object)"Scanning for base‑game HDRP + Shader Graph shaders...");
		Shader[] array = Resources.FindObjectsOfTypeAll<Shader>();
		foreach (Shader val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			string name = ((Object)val).name;
			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 (!BaseGameHDRPShaders.TryGetValue(name, out var value))
			{
				BaseGameHDRPShaders[name] = val;
				Plugin.Logger.LogInfo((object)$"Cached base‑game shader: {name} (ID {instanceID})");
				continue;
			}
			int instanceID2 = ((Object)value).GetInstanceID();
			if (instanceID2 <= 0 || instanceID < instanceID2)
			{
				BaseGameHDRPShaders[name] = val;
				Plugin.Logger.LogInfo((object)$"Updated base‑game shader: {name} → lower ID {instanceID} (was {instanceID2})");
			}
		}
		Plugin.Logger.LogInfo((object)$"Captured {BaseGameHDRPShaders.Count} base‑game 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", "1.0.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private const string GUID = "TKronix.VRShaderFix";

		private const string NAME = "VRShaderFix";

		private const string VERSION = "1.0.0.0";

		private static InputAction hotkey = null;

		private static InputAction hotkey2 = null;

		private static InputAction hotkey3 = null;

		private static int PressCount = 0;

		private static int PressCount2 = 0;

		private static int moonID = 12;

		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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			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);
			hotkey.performed += delegate
			{
				ShaderFixHost.StartShaderFix();
			};
			hotkey2.performed += delegate
			{
				Hotkey2();
			};
			hotkey3.performed += delegate
			{
				Hotkey3();
			};
			DisableHotkeys();
			if (VRConfig.enableDebug.Value)
			{
				hotkey.Enable();
				hotkey2.Enable();
				hotkey3.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("SampleSceneRelay", 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>();
			foreach (Material val3 in array)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					Logger.LogInfo((object)("Loaded Material: " + ((Object)val3).name));
					ShaderFixHost.CustomShaders.Add(((Object)val3.shader).name, val3.shader);
				}
			}
			ShaderFixHost.CachedBlacklist = (from s in VRConfig.blacklistedScenes.Value.Split(',')
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s).ToHashSet<string>(StringComparer.OrdinalIgnoreCase);
			val2.Unload(false);
			val2 = null;
			SceneManager.sceneLoaded -= InitalizeVRShaderFix;
			SceneManager.sceneLoaded += ApplyVRFixOnSceneLoad;
			ShaderFixHost.StartShaderFix();
		}

		private void CheckScene(Scene scene, LoadSceneMode mode)
		{
			if (((Scene)(ref scene)).name.Equals("SampleSceneRelay", StringComparison.OrdinalIgnoreCase))
			{
				SceneManager.sceneLoaded += ApplyVRFixOnSceneLoad;
				SceneManager.sceneLoaded -= CheckScene;
			}
		}

		private void ApplyVRFixOnSceneLoad(Scene scene, LoadSceneMode mode)
		{
			if (VRConfig.enableLogSceneToConsole.Value)
			{
				string text = "Use name below for Blacklisting";
				string name = ((Scene)(ref scene)).name;
				int num = Mathf.Max(text.Length, name.Length) + 6;
				string text2 = "╔" + new string('═', num) + "╗";
				string text3 = "║" + Center(text, num) + "║";
				string text4 = "║" + Center(name, num) + "║";
				string text5 = "╚" + new string('═', num) + "╝";
				Logger.LogInfo((object)text2);
				Logger.LogInfo((object)text3);
				Logger.LogInfo((object)text4);
				Logger.LogInfo((object)text5);
			}
			if (((Scene)(ref scene)).name.Equals("MainMenu", StringComparison.OrdinalIgnoreCase))
			{
				SceneManager.sceneLoaded -= ApplyVRFixOnSceneLoad;
				SceneManager.sceneLoaded += CheckScene;
			}
			else
			{
				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_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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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)
			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)
			{
				val2.CloseQuickMenu();
			}
			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)
					{
						int num = StartOfRound.Instance.levels.Count() - 1;
						if (moonID < num)
						{
							StartOfRound.Instance.ChangeLevel(moonID);
						}
						else
						{
							moonID = 12;
						}
						ShaderFixHost.StartCheckMissingShaders();
						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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			QuickMenuManager val = Object.FindObjectOfType<QuickMenuManager>();
			if (val.isMenuOpen)
			{
				val.CloseQuickMenu();
			}
			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();
			}
		}
	}
	internal class VRSFConfig
	{
		public readonly ConfigEntry<bool> enableBlacklist;

		public readonly ConfigEntry<bool> enableLogSceneToConsole;

		public readonly ConfigEntry<string> blacklistedScenes;

		public readonly ConfigEntry<bool> enableHarmonyPatches;

		public readonly ConfigEntry<bool> enableDebug;

		public VRSFConfig(ConfigFile cfg)
		{
			enableLogSceneToConsole = cfg.Bind<bool>("Blacklist", "EnableLogSceneNameToConsole", false, "Enable or disable Logging of Scene Name to Console");
			enableBlacklist = cfg.Bind<bool>("Blacklist", "EnableBlacklist", false, "Enable or disable the scene blacklist system");
			blacklistedScenes = cfg.Bind<string>("Blacklist", "BlacklistedScenes", "ExampleSceneName1, ExampleSceneName2", "List of scene names to NOT replace shaders/materials on.\n(Separated by commas)");
			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 MaterialUtils
	{
		public static void CopyMaterialProperties(Material source, Material target)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected I4, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)source == (Object)null || (Object)(object)target == (Object)null)
			{
				return;
			}
			target.renderQueue = source.renderQueue;
			target.globalIlluminationFlags = source.globalIlluminationFlags;
			CopyShaderKeywords(source, target);
			Shader shader = source.shader;
			int propertyCount = shader.GetPropertyCount();
			for (int i = 0; i < propertyCount; i++)
			{
				string propertyName = shader.GetPropertyName(i);
				ShaderPropertyType propertyType = shader.GetPropertyType(i);
				if (!target.HasProperty(propertyName))
				{
					continue;
				}
				switch ((int)propertyType)
				{
				case 0:
					target.SetColor(propertyName, source.GetColor(propertyName));
					break;
				case 1:
					target.SetVector(propertyName, source.GetVector(propertyName));
					break;
				case 2:
				case 3:
					target.SetFloat(propertyName, source.GetFloat(propertyName));
					break;
				case 4:
				{
					Texture texture = source.GetTexture(propertyName);
					target.SetTexture(propertyName, texture);
					if ((Object)(object)texture != (Object)null)
					{
						target.SetTextureOffset(propertyName, source.GetTextureOffset(propertyName));
						target.SetTextureScale(propertyName, source.GetTextureScale(propertyName));
					}
					break;
				}
				}
			}
			CopyMainTextureShortcuts(source, target);
		}

		private static void CopyShaderKeywords(Material source, Material target)
		{
			HashSet<string> hashSet = new HashSet<string>(source.shaderKeywords);
			string[] shaderKeywords = target.shaderKeywords;
			foreach (string item in shaderKeywords)
			{
				hashSet.Add(item);
			}
			target.shaderKeywords = hashSet.ToArray();
		}

		private static void CopyMainTextureShortcuts(Material source, Material target)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (target.HasProperty("_MainTex"))
			{
				target.mainTexture = source.mainTexture;
				target.mainTextureOffset = source.mainTextureOffset;
				target.mainTextureScale = source.mainTextureScale;
			}
		}
	}
	public static class VRFixUtils
	{
		private static readonly string[] DefaultExcludedScenes = new string[3] { "MainMenu", "DontDestroyOnLoad", "HideAndDontSave" };

		public static List<T> FindAllInLoadedScenes<T>(params string[] excludedScenes) where T : Component
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (excludedScenes == null || excludedScenes.Length == 0)
			{
				excludedScenes = DefaultExcludedScenes;
			}
			List<T> list = new List<T>();
			int sceneCount = SceneManager.sceneCount;
			for (int i = 0; i < sceneCount; i++)
			{
				Scene sceneAt = SceneManager.GetSceneAt(i);
				if (((Scene)(ref sceneAt)).isLoaded && !excludedScenes.Contains(((Scene)(ref sceneAt)).name))
				{
					GameObject[] rootGameObjects = ((Scene)(ref sceneAt)).GetRootGameObjects();
					foreach (GameObject val in rootGameObjects)
					{
						list.AddRange(val.GetComponentsInChildren<T>(true));
					}
				}
			}
			return list;
		}

		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)
		{
		}
	}
}