Decompiled source of Comic Book v1.0.1

EmpressCelshade.dll

Decompiled 2 months 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.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Omniscye")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EmpressCelshade")]
[assembly: AssemblyTitle("EmpressCelshade")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Empress.MaterialSwap
{
	[BepInPlugin("empress.repo.materialswap", "Empress Material Swap", "1.4.0")]
	public class EmpressMaterialSwapPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <BurstRescans>d__49 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public EmpressMaterialSwapPlugin <>4__this;

			private int <n>5__1;

			private float <dt>5__2;

			private int <i>5__3;

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

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

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

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

			private bool MoveNext()
			{
				//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<n>5__1 = Mathf.Max(0, _burstRescans.Value);
					<dt>5__2 = Mathf.Max(0f, _burstIntervalSeconds.Value);
					<i>5__3 = 0;
					break;
				case 1:
					<>1__state = -1;
					goto IL_00d2;
				case 2:
					{
						<>1__state = -1;
						goto IL_00d2;
					}
					IL_00d2:
					<i>5__3++;
					break;
				}
				if (<i>5__3 < <n>5__1)
				{
					if (!_enabled.Value)
					{
						return false;
					}
					RunSwapOnAllOpenScenes();
					if (<dt>5__2 <= 0f)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<>2__current = (object)new WaitForSeconds(<dt>5__2);
					<>1__state = 2;
					return true;
				}
				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();
			}
		}

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

			private object <>2__current;

			public EmpressMaterialSwapPlugin <>4__this;

			private WaitForSeconds <wait>5__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<wait>5__1 = new WaitForSeconds(Mathf.Max(0.1f, _periodicScanSeconds.Value));
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (_enabled.Value)
				{
					RunSwapOnAllOpenScenes();
				}
				<>2__current = <wait>5__1;
				<>1__state = 1;
				return true;
			}

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

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

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

			private object <>2__current;

			public EmpressMaterialSwapPlugin <>4__this;

			private float <t>5__1;

			private float <timeout>5__2;

			private LevelGenerator <lg>5__3;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<t>5__1 = 0f;
					<timeout>5__2 = Mathf.Max(2f, _levelReadyTimeout.Value);
					goto IL_00c0;
				case 1:
					<>1__state = -1;
					goto IL_00c0;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_00c0:
					if (<t>5__1 < <timeout>5__2)
					{
						try
						{
							<lg>5__3 = LevelGenerator.Instance;
							if (!((Object)(object)<lg>5__3 != (Object)null) || !<lg>5__3.Generated)
							{
								<lg>5__3 = null;
								goto IL_0096;
							}
						}
						catch
						{
							goto IL_0096;
						}
					}
					RunSwapOnAllOpenScenes();
					if (_burstRescans.Value > 0)
					{
						<>2__current = <>4__this.BurstRescans();
						<>1__state = 2;
						return true;
					}
					break;
					IL_0096:
					<t>5__1 += Time.unscaledDeltaTime;
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				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();
			}
		}

		public const string Guid = "empress.repo.materialswap";

		public const string Name = "Empress Material Swap";

		public const string Version = "1.4.0";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<string> _assetBundleName;

		private static ConfigEntry<string> _singleMaterialName;

		private static ConfigEntry<bool> _useSingleMaterialForAll;

		private static ConfigEntry<bool> _matchByMaterialName;

		private static ConfigEntry<bool> _fallbackToSingleIfNoMatch;

		private static ConfigEntry<bool> _includeSkybox;

		private static ConfigEntry<bool> _copyCommonProps;

		private static ConfigEntry<int> _burstRescans;

		private static ConfigEntry<float> _burstIntervalSeconds;

		private static ConfigEntry<float> _periodicScanSeconds;

		private static ConfigEntry<bool> _listBundleAssets;

		private static ConfigEntry<bool> _onlyMeshRenderers;

		private static ConfigEntry<bool> _excludeUILayer;

		private static ConfigEntry<bool> _excludeCanvasHierarchy;

		private static ConfigEntry<bool> _excludeCanvasRenderer;

		private static ConfigEntry<bool> _excludeUnderCameraHierarchy;

		private static ConfigEntry<bool> _excludePlayerHierarchy;

		private static ConfigEntry<string> _excludeLayersCsv;

		private static ConfigEntry<string> _excludeTagsCsv;

		private static ConfigEntry<bool> _excludeTransparentQueue;

		private static ConfigEntry<bool> _excludeOverlayQueue;

		private static ConfigEntry<bool> _excludeDepthOnlyShaders;

		private static ConfigEntry<bool> _excludeParticleShaders;

		private static ConfigEntry<bool> _excludeUIShaders;

		private static ConfigEntry<bool> _excludeFXShaders;

		private static ConfigEntry<bool> _excludeSkyboxShaders;

		private static ConfigEntry<string> _excludeShaderNameContainsCsv;

		private static ConfigEntry<float> _levelReadyTimeout;

		private static readonly HashSet<int> _excludedLayers = new HashSet<int>();

		private static readonly HashSet<string> _excludedTags = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly List<string> _excludedShaderSubstrings = new List<string>();

		private static readonly Dictionary<string, Material> _bundleMatsByLeaf = new Dictionary<string, Material>(StringComparer.OrdinalIgnoreCase);

		private static Material _singleMaterial;

		private static readonly Dictionary<int, Material> _materialCache = new Dictionary<int, Material>(2048);

		private static EmpressMaterialSwapPlugin _instance;

		private static EmpressMaterialSwapPlugin Instance => _instance ?? (_instance = Object.FindObjectOfType<EmpressMaterialSwapPlugin>());

		private void Awake()
		{
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Expected O, but got Unknown
			_instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle for material swapping.");
			_includeSkybox = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IncludeSkybox", false, "Also replace RenderSettings.skybox if a named match exists or single material is set.");
			_copyCommonProps = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "CopyCommonProperties", false, "Copy textures/colors/floats from source to replacement when properties exist.");
			_periodicScanSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PeriodicScanSeconds", 0f, "How often to rescan for new renderers (0 disables). Enable only for streamed scenes.");
			_burstRescans = ((BaseUnityPlugin)this).Config.Bind<int>("General", "BurstRescans", 0, "Extra rescans after a scene change to catch late spawns.");
			_burstIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "BurstIntervalSeconds", 0.5f, "Seconds between burst rescans.");
			_levelReadyTimeout = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LevelReadyTimeout", 20f, "Max seconds to wait for LevelGenerator.Instance.Generated before first swap each scene.");
			_assetBundleName = ((BaseUnityPlugin)this).Config.Bind<string>("Bundle", "AssetBundleName", "empress", "AssetBundle filename (without extension) next to this DLL.");
			_useSingleMaterialForAll = ((BaseUnityPlugin)this).Config.Bind<bool>("Bundle", "UseSingleMaterialForAll", true, "If true, replace all materials with one material from the bundle.");
			_singleMaterialName = ((BaseUnityPlugin)this).Config.Bind<string>("Bundle", "SingleMaterialName", "empressomni", "Name of the material inside the bundle to use when UseSingleMaterialForAll is true.");
			_matchByMaterialName = ((BaseUnityPlugin)this).Config.Bind<bool>("Mapping", "MatchByMaterialName", true, "Try to find a bundle material with the same name as the source material (case-insensitive).");
			_fallbackToSingleIfNoMatch = ((BaseUnityPlugin)this).Config.Bind<bool>("Mapping", "FallbackToSingleIfNoMatch", true, "If no name match, fall back to the single material.");
			_onlyMeshRenderers = ((BaseUnityPlugin)this).Config.Bind<bool>("Targeting", "OnlyMeshRenderers", true, "Only MeshRenderer and SkinnedMeshRenderer are processed.");
			_excludeUILayer = ((BaseUnityPlugin)this).Config.Bind<bool>("Targeting", "ExcludeUILayer", true, "Exclude objects on the Unity UI layer (5).");
			_excludeCanvasHierarchy = ((BaseUnityPlugin)this).Config.Bind<bool>("Targeting", "ExcludeCanvasHierarchy", true, "Exclude any renderer under a Canvas (including World Space UI).");
			_excludeCanvasRenderer = ((BaseUnityPlugin)this).Config.Bind<bool>("Targeting", "ExcludeCanvasRenderer", true, "Exclude GameObjects that have a CanvasRenderer component.");
			_excludeUnderCameraHierarchy = ((BaseUnityPlugin)this).Config.Bind<bool>("Targeting", "ExcludeUnderCameraHierarchy", true, "Exclude any renderer that has a Camera in its parent hierarchy.");
			_excludePlayerHierarchy = ((BaseUnityPlugin)this).Config.Bind<bool>("Targeting", "ExcludePlayerHierarchy", true, "Exclude any renderer that has a PlayerController in its parent hierarchy.");
			_excludeLayersCsv = ((BaseUnityPlugin)this).Config.Bind<string>("Targeting", "ExcludeLayers", "UI", "Comma-separated extra layers to exclude (names or indices). Example: UI, 9, 10.");
			_excludeTagsCsv = ((BaseUnityPlugin)this).Config.Bind<string>("Targeting", "ExcludeTags", "UI, IgnoreSwap", "Comma-separated tags to exclude.");
			_excludeTransparentQueue = ((BaseUnityPlugin)this).Config.Bind<bool>("MaterialFilters", "ExcludeTransparentQueue", true, "Skip materials with renderQueue >= 3000 (Transparent and up).");
			_excludeOverlayQueue = ((BaseUnityPlugin)this).Config.Bind<bool>("MaterialFilters", "ExcludeOverlayQueue", true, "Skip materials with renderQueue >= 4000 (Overlay).");
			_excludeDepthOnlyShaders = ((BaseUnityPlugin)this).Config.Bind<bool>("MaterialFilters", "ExcludeDepthOnlyShaders", true, "Skip shaders whose names contain 'DepthOnly'.");
			_excludeParticleShaders = ((BaseUnityPlugin)this).Config.Bind<bool>("MaterialFilters", "ExcludeParticleShaders", true, "Skip shaders whose names contain 'Particle'.");
			_excludeUIShaders = ((BaseUnityPlugin)this).Config.Bind<bool>("MaterialFilters", "ExcludeUIShaders", true, "Skip shaders whose names contain 'UI'.");
			_excludeFXShaders = ((BaseUnityPlugin)this).Config.Bind<bool>("MaterialFilters", "ExcludeFXShaders", true, "Skip shaders whose names contain 'FX'.");
			_excludeSkyboxShaders = ((BaseUnityPlugin)this).Config.Bind<bool>("MaterialFilters", "ExcludeSkyboxShaders", true, "Skip shaders whose names contain 'Skybox'.");
			_excludeShaderNameContainsCsv = ((BaseUnityPlugin)this).Config.Bind<string>("MaterialFilters", "ExcludeShaderNameContains", "Hidden, PostProcess, Post-Process, Overlay", "Extra comma-separated substrings that, if found in shader name, exclude the material.");
			_listBundleAssets = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ListBundleAssets", false, "If true, log all asset names in the bundle at load time.");
			ParseFilters();
			_harmony = new Harmony("empress.repo.materialswap");
			_harmony.PatchAll();
			TryLoadMaterialsFromBundle();
			SceneManager.sceneLoaded += OnSceneLoaded;
			SceneManager.activeSceneChanged += OnActiveSceneChanged;
			((MonoBehaviour)this).StartCoroutine(WaitForLevelThenSwap());
			if (_periodicScanSeconds.Value > 0f)
			{
				((MonoBehaviour)this).StartCoroutine(PeriodicScan());
			}
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			SceneManager.activeSceneChanged -= OnActiveSceneChanged;
			try
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
		}

		private void ParseFilters()
		{
			_excludedLayers.Clear();
			if (_excludeUILayer.Value)
			{
				_excludedLayers.Add(5);
			}
			string[] array = (_excludeLayersCsv.Value ?? string.Empty).Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				string text2 = text.Trim();
				if (text2.Length == 0)
				{
					continue;
				}
				if (int.TryParse(text2, out var result))
				{
					_excludedLayers.Add(Mathf.Clamp(result, 0, 31));
					continue;
				}
				int num = LayerMask.NameToLayer(text2);
				if (num >= 0)
				{
					_excludedLayers.Add(num);
				}
			}
			_excludedTags.Clear();
			string[] array2 = (_excludeTagsCsv.Value ?? string.Empty).Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text3 in array2)
			{
				string text4 = text3.Trim();
				if (text4.Length > 0)
				{
					_excludedTags.Add(text4);
				}
			}
			_excludedShaderSubstrings.Clear();
			string[] array3 = (_excludeShaderNameContainsCsv.Value ?? string.Empty).Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text5 in array3)
			{
				string text6 = text5.Trim();
				if (!string.IsNullOrEmpty(text6))
				{
					_excludedShaderSubstrings.Add(text6);
				}
			}
		}

		private static void OnActiveSceneChanged(Scene oldScene, Scene newScene)
		{
			if (_enabled.Value && (Object)(object)Instance != (Object)null)
			{
				((MonoBehaviour)Instance).StartCoroutine(Instance.WaitForLevelThenSwap());
			}
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (_enabled.Value && (Object)(object)Instance != (Object)null)
			{
				((MonoBehaviour)Instance).StartCoroutine(Instance.WaitForLevelThenSwap());
			}
		}

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

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

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

		private void TryLoadMaterialsFromBundle()
		{
			try
			{
				string location = typeof(EmpressMaterialSwapPlugin).Assembly.Location;
				string path = Path.GetDirectoryName(location) ?? Directory.GetCurrentDirectory();
				string[] array = new string[4] { "", ".bundle", ".assets", ".ab" };
				string text = null;
				string[] array2 = array;
				foreach (string text2 in array2)
				{
					string text3 = Path.Combine(path, _assetBundleName.Value + text2);
					if (File.Exists(text3))
					{
						text = text3;
						break;
					}
				}
				if (text == null)
				{
					Log.LogWarning((object)("AssetBundle '" + _assetBundleName.Value + "' not found next to plugin."));
					return;
				}
				AssetBundle val = AssetBundle.LoadFromFile(text);
				if ((Object)(object)val == (Object)null)
				{
					Log.LogError((object)("Failed to load AssetBundle: " + text));
					return;
				}
				if (_listBundleAssets.Value)
				{
					string[] allAssetNames = val.GetAllAssetNames();
					Log.LogInfo((object)("[Bundle " + _assetBundleName.Value + "] assets (" + allAssetNames.Length + "):"));
					for (int j = 0; j < allAssetNames.Length; j++)
					{
						Log.LogInfo((object)(" - " + allAssetNames[j]));
					}
				}
				_bundleMatsByLeaf.Clear();
				Material[] array3 = val.LoadAllAssets<Material>();
				foreach (Material val2 in array3)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						string name = ((Object)val2).name;
						if (!_bundleMatsByLeaf.ContainsKey(name))
						{
							_bundleMatsByLeaf.Add(name, val2);
						}
					}
				}
				_singleMaterial = null;
				if (_useSingleMaterialForAll.Value)
				{
					_singleMaterial = SafeLoadMaterial(val, _singleMaterialName.Value) ?? TryFindMaterialLoose(val, _singleMaterialName.Value);
					if ((Object)(object)_singleMaterial != (Object)null)
					{
						Log.LogInfo((object)("Loaded single replacement material: " + ((Object)_singleMaterial).name));
					}
					else
					{
						Log.LogWarning((object)("Single material '" + _singleMaterialName.Value + "' not found in bundle '" + _assetBundleName.Value + "'."));
					}
				}
				val.Unload(false);
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Bundle load exception: " + ex));
			}
		}

		private static Material SafeLoadMaterial(AssetBundle bundle, string name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return null;
			}
			try
			{
				return bundle.LoadAsset<Material>(name);
			}
			catch
			{
				return null;
			}
		}

		private static Material TryFindMaterialLoose(AssetBundle bundle, string requested)
		{
			if (string.IsNullOrWhiteSpace(requested))
			{
				return null;
			}
			string reqLower = requested.Trim().ToLowerInvariant();
			try
			{
				string[] allAssetNames = bundle.GetAllAssetNames();
				string text = allAssetNames.FirstOrDefault((string a) => a.EndsWith("/" + reqLower) || Path.GetFileNameWithoutExtension(a) == reqLower);
				if (text != null)
				{
					return bundle.LoadAsset<Material>(text);
				}
			}
			catch
			{
			}
			return null;
		}

		private static void RunSwapOnAllOpenScenes()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (!_enabled.Value)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			try
			{
				if (_includeSkybox.Value && (Object)(object)RenderSettings.skybox != (Object)null && !ShouldIgnoreMaterial(RenderSettings.skybox) && TryGetReplacementFor(RenderSettings.skybox, out Material result))
				{
					RenderSettings.skybox = result;
					num++;
				}
				int sceneCount = SceneManager.sceneCount;
				for (int i = 0; i < sceneCount; i++)
				{
					Scene sceneAt = SceneManager.GetSceneAt(i);
					if (!((Scene)(ref sceneAt)).isLoaded)
					{
						continue;
					}
					GameObject[] rootGameObjects = ((Scene)(ref sceneAt)).GetRootGameObjects();
					foreach (GameObject val in rootGameObjects)
					{
						Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
						foreach (Renderer val2 in componentsInChildren)
						{
							if (ShouldIgnoreRenderer(val2))
							{
								continue;
							}
							num2++;
							Material[] sharedMaterials = val2.sharedMaterials;
							bool flag = false;
							for (int l = 0; l < sharedMaterials.Length; l++)
							{
								Material val3 = sharedMaterials[l];
								if (!((Object)(object)val3 == (Object)null) && !ShouldIgnoreMaterial(val3) && TryGetReplacementFor(val3, out Material result2))
								{
									sharedMaterials[l] = result2;
									flag = true;
									num++;
								}
							}
							if (flag)
							{
								val2.sharedMaterials = sharedMaterials;
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Swap exception: " + ex));
			}
		}

		private static bool ShouldIgnoreRenderer(Renderer r)
		{
			if ((Object)(object)r == (Object)null)
			{
				return true;
			}
			GameObject gameObject = ((Component)r).gameObject;
			if (!gameObject.activeInHierarchy || !r.enabled)
			{
				return true;
			}
			if (_excludedLayers.Contains(gameObject.layer))
			{
				return true;
			}
			if (_excludedTags.Count > 0 && _excludedTags.Contains(gameObject.tag))
			{
				return true;
			}
			if (_excludeCanvasHierarchy.Value)
			{
				try
				{
					if ((Object)(object)((Component)r).GetComponentInParent<Canvas>(true) != (Object)null)
					{
						return true;
					}
				}
				catch
				{
				}
			}
			if (_excludeCanvasRenderer.Value)
			{
				try
				{
					if ((Object)(object)gameObject.GetComponent<CanvasRenderer>() != (Object)null)
					{
						return true;
					}
				}
				catch
				{
				}
			}
			if (_excludeUnderCameraHierarchy.Value)
			{
				try
				{
					if ((Object)(object)((Component)r).GetComponentInParent<Camera>(true) != (Object)null)
					{
						return true;
					}
				}
				catch
				{
				}
			}
			if (_excludePlayerHierarchy.Value)
			{
				try
				{
					PlayerController instance = PlayerController.instance;
					if ((Object)(object)instance != (Object)null)
					{
						if ((Object)(object)((Component)r).transform != (Object)null && ((Component)r).transform.IsChildOf(((Component)instance).transform))
						{
							return true;
						}
					}
					else if ((Object)(object)((Component)r).GetComponentInParent<PlayerController>(true) != (Object)null)
					{
						return true;
					}
				}
				catch
				{
				}
			}
			if (_onlyMeshRenderers.Value)
			{
				if (!(r is MeshRenderer) && !(r is SkinnedMeshRenderer))
				{
					return true;
				}
			}
			else if (r is ParticleSystemRenderer || r is LineRenderer || r is TrailRenderer)
			{
				return true;
			}
			return false;
		}

		private static bool ShouldIgnoreMaterial(Material mat)
		{
			if ((Object)(object)mat == (Object)null)
			{
				return true;
			}
			try
			{
				int renderQueue = mat.renderQueue;
				if (_excludeOverlayQueue.Value && renderQueue >= 4000)
				{
					return true;
				}
				if (_excludeTransparentQueue.Value && renderQueue >= 3000)
				{
					return true;
				}
				Shader shader = mat.shader;
				string text = (((Object)(object)shader != (Object)null) ? (((Object)shader).name ?? string.Empty) : string.Empty);
				string text2 = text.ToLowerInvariant();
				if (_excludeDepthOnlyShaders.Value && text2.Contains("depthonly"))
				{
					return true;
				}
				if (_excludeParticleShaders.Value && text2.Contains("particle"))
				{
					return true;
				}
				if (_excludeUIShaders.Value && text2.Contains("ui"))
				{
					return true;
				}
				if (_excludeFXShaders.Value && text2.Contains("fx"))
				{
					return true;
				}
				if (_excludeSkyboxShaders.Value && text2.Contains("skybox"))
				{
					return true;
				}
				if (_excludedShaderSubstrings.Count > 0)
				{
					for (int i = 0; i < _excludedShaderSubstrings.Count; i++)
					{
						string value = _excludedShaderSubstrings[i];
						if (!string.IsNullOrEmpty(value) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
						{
							return true;
						}
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static string NormalizeMaterialName(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return string.Empty;
			}
			int num = name.IndexOf(" (Instance)", StringComparison.Ordinal);
			if (num >= 0)
			{
				name = name.Substring(0, num);
			}
			num = name.IndexOf(" (Clone)", StringComparison.Ordinal);
			if (num >= 0)
			{
				name = name.Substring(0, num);
			}
			return name.Trim();
		}

		private static bool TryGetReplacementFor(Material source, out Material result)
		{
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			result = null;
			if ((Object)(object)source == (Object)null)
			{
				return false;
			}
			int instanceID = ((Object)source).GetInstanceID();
			if (_materialCache.TryGetValue(instanceID, out Material value))
			{
				result = value;
				return true;
			}
			Material value2 = null;
			if (_matchByMaterialName.Value && _bundleMatsByLeaf.Count > 0)
			{
				string key = NormalizeMaterialName(((Object)source).name);
				_bundleMatsByLeaf.TryGetValue(key, out value2);
			}
			if ((Object)(object)value2 == (Object)null && _useSingleMaterialForAll.Value && (Object)(object)_singleMaterial != (Object)null && _fallbackToSingleIfNoMatch.Value)
			{
				value2 = _singleMaterial;
			}
			if ((Object)(object)value2 == (Object)null)
			{
				return false;
			}
			Material val;
			if (_copyCommonProps.Value)
			{
				val = new Material(value2)
				{
					name = ((Object)value2).name + "__Empress"
				};
				TryCopyCommon(source, val);
			}
			else
			{
				val = value2;
			}
			_materialCache[instanceID] = val;
			result = val;
			return true;
		}

		private static void TryCopyCommon(Material src, Material dst)
		{
			CopyTex(src, dst, "_BaseMap");
			CopyTex(src, dst, "_MainTex");
			CopyTex(src, dst, "_BaseColorMap");
			CopyColor(src, dst, "_BaseColor");
			CopyColor(src, dst, "_Color");
			CopyFloat(src, dst, "_Metallic");
			CopyFloat(src, dst, "_Smoothness");
			CopyFloat(src, dst, "_Glossiness");
			CopyTex(src, dst, "_BumpMap");
			CopyFloat(src, dst, "_BumpScale");
			CopyTex(src, dst, "_EmissionMap");
			CopyColor(src, dst, "_EmissionColor");
			if (src.IsKeywordEnabled("_EMISSION"))
			{
				dst.EnableKeyword("_EMISSION");
			}
			CopyFloat(src, dst, "_Cutoff");
		}

		private static void CopyTex(Material src, Material dst, string name)
		{
			if (src.HasProperty(name) && dst.HasProperty(name))
			{
				try
				{
					dst.SetTexture(name, src.GetTexture(name));
				}
				catch
				{
				}
			}
		}

		private static void CopyColor(Material src, Material dst, string name)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (src.HasProperty(name) && dst.HasProperty(name))
			{
				try
				{
					dst.SetColor(name, src.GetColor(name));
				}
				catch
				{
				}
			}
		}

		private static void CopyFloat(Material src, Material dst, string name)
		{
			if (src.HasProperty(name) && dst.HasProperty(name))
			{
				try
				{
					dst.SetFloat(name, src.GetFloat(name));
				}
				catch
				{
				}
			}
		}
	}
}
namespace EmpressCelshade
{
	[BepInPlugin("Omniscye.EmpressCelshade", "EmpressCelshade", "1.0")]
	public class EmpressCelshade : BaseUnityPlugin
	{
		internal static EmpressCelshade Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
		}
	}
}