Decompiled source of PS1 Vertex Wobble v0.0.1

BRCVertexSnap.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Rewired;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace BRCVertexSnap;

public class ColorDepthEffect : MonoBehaviour
{
	public Material EffectMaterial;

	private void OnRenderImage(RenderTexture source, RenderTexture destination)
	{
		if ((Object)(object)EffectMaterial == (Object)null)
		{
			Graphics.Blit((Texture)(object)source, destination);
		}
		else
		{
			Graphics.Blit((Texture)(object)source, destination, EffectMaterial);
		}
	}
}
[BepInPlugin("brcvertexsnap.plugin", "BRC Vertex Snap", "0.3.0")]
public class VertexSnapPlugin : BaseUnityPlugin
{
	private struct TextureState
	{
		public FilterMode Filter;

		public float MipBias;
	}

	public const string PluginGuid = "brcvertexsnap.plugin";

	public const string PluginName = "BRC Vertex Snap";

	public const string PluginVersion = "0.3.0";

	private const string BundleFileName = "vertexsnap.bundle";

	private const string ReplacementPrefix = "VertexSnap/";

	private const string ReservedPostPrefix = "VertexSnap/Post/";

	private const string FallbackShaderName = "VertexSnap/Fallback Unlit";

	private const string ColorDepthShaderName = "VertexSnap/Post/ColorDepth";

	private const string VanillaCharacterShader = "Reptile/Ambient Character";

	private static readonly string[] CharacterTextureProps = new string[2] { "_MainTex", "_Emission" };

	private static readonly string[] FallbackBlockedPrefixes = new string[11]
	{
		"Hidden/", "UI/", "Sprites/", "GUI/", "TextMeshPro", "Particles/", "Legacy Shaders/Particles", "Mobile/Particles", "Skybox/", "Unlit/Swirl",
		"Reptile/Water"
	};

	private static readonly int SnapParamsId = Shader.PropertyToID("_BRCSnapParams");

	private static readonly int SnapParams2Id = Shader.PropertyToID("_BRCSnapParams2");

	private static readonly int FogParamsId = Shader.PropertyToID("_BRCFogParams");

	private static readonly int FogColorId = Shader.PropertyToID("_BRCFogColor");

	private static readonly int ColorParamsId = Shader.PropertyToID("_BRCColorParams");

	private ConfigEntry<bool> cfgEnabled;

	private ConfigEntry<KeyboardShortcut> cfgToggleKey;

	private ConfigEntry<int> cfgGridWidth;

	private ConfigEntry<int> cfgGridHeight;

	private ConfigEntry<bool> cfgDepthCorrection;

	private ConfigEntry<float> cfgOverlayBias;

	private ConfigEntry<bool> cfgAffineEnabled;

	private ConfigEntry<float> cfgAffineStrength;

	private ConfigEntry<bool> cfgColorEnabled;

	private ConfigEntry<int> cfgColorBits;

	private ConfigEntry<float> cfgDitherStrength;

	private ConfigEntry<int> cfgDitherCell;

	private ConfigEntry<bool> cfgPointFilter;

	private ConfigEntry<bool> cfgNoMipmaps;

	private ConfigEntry<bool> cfgFogEnabled;

	private ConfigEntry<Color> cfgFogColor;

	private ConfigEntry<float> cfgFogStart;

	private ConfigEntry<float> cfgFogEnd;

	private ConfigEntry<bool> cfgApplyToUnrecognized;

	private ConfigEntry<bool> cfgLogUnrecognized;

	private ConfigEntry<float> cfgSweepInterval;

	private AssetBundle bundle;

	private Shader fallbackShader;

	private Material colorDepthMaterial;

	private readonly List<ColorDepthEffect> effects = new List<ColorDepthEffect>();

	private readonly Dictionary<string, Shader> replacements = new Dictionary<string, Shader>();

	private readonly Dictionary<Material, Shader> originals = new Dictionary<Material, Shader>();

	private readonly HashSet<Material> characterMaterials = new HashSet<Material>();

	private readonly Dictionary<Texture, TextureState> textureOriginals = new Dictionary<Texture, TextureState>();

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

	private bool texturesPoint;

	private bool texturesNoMips;

	private float nextSweepTime;

	private int sweepCounter;

	private bool ready;

	private float lastToggleTime = -10f;

	private bool legacyInputBroken;

	private bool rewiredBroken;

	private void Awake()
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Expected O, but got Unknown
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Expected O, but got Unknown
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Expected O, but got Unknown
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Expected O, but got Unknown
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Expected O, but got Unknown
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Expected O, but got Unknown
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Expected O, but got Unknown
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0310: Unknown result type (might be due to invalid IL or missing references)
		//IL_031a: Expected O, but got Unknown
		//IL_034e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0358: Expected O, but got Unknown
		//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d8: Expected O, but got Unknown
		//IL_0462: Unknown result type (might be due to invalid IL or missing references)
		//IL_0467: Unknown result type (might be due to invalid IL or missing references)
		cfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. Turns the whole mod (snap and every extra effect) on or off.");
		cfgToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Toggle Hotkey", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), "Press this key in game to toggle the master switch.");
		cfgGridWidth = ((BaseUnityPlugin)this).Config.Bind<int>("Snap", "Grid Width", 320, new ConfigDescription("Number of snap steps across the screen horizontally. Lower values give a stronger wobble.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 7680), Array.Empty<object>()));
		cfgGridHeight = ((BaseUnityPlugin)this).Config.Bind<int>("Snap", "Grid Height", 180, new ConfigDescription("Number of snap steps across the screen vertically. Lower values give a stronger wobble.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 4320), Array.Empty<object>()));
		cfgDepthCorrection = ((BaseUnityPlugin)this).Config.Bind<bool>("Snap", "Surface Depth Correction", true, "Keeps snapped vertices on their original surface plane. This stops layered geometry (floors with decal planes on top) from z-fighting when the snap moves them. Turn off to get the raw PS1 behaviour, where overlapping surfaces fight.");
		cfgOverlayBias = ((BaseUnityPlugin)this).Config.Bind<float>("Snap", "Overlay Depth Bias", 0f, new ConfigDescription("Pushes decals and transparent overlays towards the camera (units of 0.00001 NDC depth). Raise it if overlays on top of floors still flicker or sink into the surface below. 0 = off.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
		cfgAffineEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Affine Texture Mapping", "Enabled", true, "PS1 style texture warping: textures are interpolated linearly in screen space instead of perspective correct, so they swim on large polygons. Only affects the game's own shaders.");
		cfgAffineStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Affine Texture Mapping", "Strength", 1f, new ConfigDescription("0 = normal perspective correct textures, 1 = full affine warping.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		cfgColorEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Color Depth", "Enabled", true, "Reduces the color depth of the final image (PS1 used 15 bit color) with an ordered dither. The UI is not affected.");
		cfgColorBits = ((BaseUnityPlugin)this).Config.Bind<int>("Color Depth", "Bits Per Channel", 5, new ConfigDescription("Bits per color channel. 5 = PS1 (15 bit color). Lower values are more extreme.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>()));
		cfgDitherStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Color Depth", "Dither Strength", 1f, new ConfigDescription("0 = no dithering (visible color banding), 1 = full ordered dither.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		cfgDitherCell = ((BaseUnityPlugin)this).Config.Bind<int>("Color Depth", "Dither Cell Size", 2, new ConfigDescription("Size of one dither dot in screen pixels. Raise it on high resolution screens to make the pattern visible.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>()));
		cfgPointFilter = ((BaseUnityPlugin)this).Config.Bind<bool>("Character Textures", "Point Filtering", true, "Removes texture smoothing on the game's own characters. CrewBoom and other custom characters are not touched.");
		cfgNoMipmaps = ((BaseUnityPlugin)this).Config.Bind<bool>("Character Textures", "Disable Mipmaps", true, "Always samples the sharpest mip level on the character textures (only used together with Point Filtering).");
		cfgFogEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Fog", "Enabled", false, "Short distance fog. The game's own shaders have no fog, so this adds it. Match the color to the sky of the level you are in.");
		cfgFogColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Fog", "Color", new Color(0.55f, 0.6f, 0.7f, 1f), "Fog color.");
		cfgFogStart = ((BaseUnityPlugin)this).Config.Bind<float>("Fog", "Start Distance", 25f, new ConfigDescription("Distance where the fog starts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), Array.Empty<object>()));
		cfgFogEnd = ((BaseUnityPlugin)this).Config.Bind<float>("Fog", "End Distance", 120f, new ConfigDescription("Distance where everything is fully fogged.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), Array.Empty<object>()));
		cfgApplyToUnrecognized = ((BaseUnityPlugin)this).Config.Bind<bool>("Coverage", "Apply To Unrecognized Shaders", false, "EXPERIMENTAL. Replaces unknown opaque mesh shaders (for example from mods) with a simple unlit shader that supports snapping. The replaced objects lose their original lighting.");
		cfgLogUnrecognized = ((BaseUnityPlugin)this).Config.Bind<bool>("Coverage", "Log Unrecognized Shaders", true, "Writes the name of every shader the plugin does not know to the BepInEx log (once per shader).");
		cfgSweepInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Advanced", "Sweep Interval Seconds", 1f, new ConfigDescription("How often the plugin looks for new materials, cameras and character textures to patch.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), Array.Empty<object>()));
		if (LoadBundle())
		{
			cfgEnabled.SettingChanged += delegate
			{
				OnEnabledChanged();
			};
			SceneManager.sceneLoaded += OnSceneLoaded;
			ready = true;
			PushGlobals(cfgEnabled.Value);
			if (cfgEnabled.Value)
			{
				Sweep();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("BRC Vertex Snap 0.3.0 loaded. " + replacements.Count + " shader replacements available. Toggle hotkey: " + ((object)cfgToggleKey.Value/*cast due to .constrained prefix*/).ToString()));
		}
	}

	private bool LoadBundle()
	{
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Expected O, but got Unknown
		string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		string text = Path.Combine(directoryName, "vertexsnap.bundle");
		if (!File.Exists(text))
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Missing vertexsnap.bundle next to the plugin DLL (" + directoryName + "). The effect is disabled."));
			return false;
		}
		bundle = AssetBundle.LoadFromFile(text);
		if ((Object)(object)bundle == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load " + text + ". It must be built with Unity 2021.3.20f1 for Windows 64-bit."));
			return false;
		}
		Shader[] array = bundle.LoadAllAssets<Shader>();
		foreach (Shader val in array)
		{
			if (!((Object)(object)val == (Object)null))
			{
				if (!val.isSupported)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Shader not supported on this GPU / failed to compile: " + ((Object)val).name));
				}
				else if (((Object)val).name == "VertexSnap/Fallback Unlit")
				{
					fallbackShader = val;
				}
				else if (((Object)val).name == "VertexSnap/Post/ColorDepth")
				{
					colorDepthMaterial = new Material(val);
					((Object)colorDepthMaterial).hideFlags = (HideFlags)61;
				}
				else if (!((Object)val).name.StartsWith("VertexSnap/Post/") && ((Object)val).name.StartsWith("VertexSnap/"))
				{
					replacements[((Object)val).name.Substring("VertexSnap/".Length)] = val;
				}
			}
		}
		if ((Object)(object)colorDepthMaterial == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Color depth shader missing or not supported, the Color Depth effect is unavailable.");
		}
		return true;
	}

	private void Update()
	{
		if (TogglePressed())
		{
			cfgEnabled.Value = !cfgEnabled.Value;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Vertex snap " + (cfgEnabled.Value ? "enabled" : "disabled") + " (hotkey)"));
		}
		if (ready)
		{
			bool value = cfgEnabled.Value;
			PushGlobals(value);
			UpdatePostEffect(value);
			UpdateCharacterTextures(value);
			if (value && Time.unscaledTime >= nextSweepTime)
			{
				Sweep();
			}
		}
	}

	private bool TogglePressed()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		if (Time.unscaledTime - lastToggleTime < 0.35f)
		{
			return false;
		}
		KeyboardShortcut value = cfgToggleKey.Value;
		bool flag = false;
		try
		{
			flag = ((KeyboardShortcut)(ref value)).IsDown();
		}
		catch (Exception)
		{
		}
		if (!flag && !legacyInputBroken)
		{
			try
			{
				flag = Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey);
			}
			catch (Exception ex2)
			{
				legacyInputBroken = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Unity legacy Input is not available: " + ex2.Message));
			}
		}
		if (!flag && !rewiredBroken)
		{
			try
			{
				flag = RewiredKeyDown(((KeyboardShortcut)(ref value)).MainKey);
			}
			catch (Exception ex3)
			{
				rewiredBroken = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Rewired keyboard is not available: " + ex3.Message));
			}
		}
		if (flag)
		{
			lastToggleTime = Time.unscaledTime;
		}
		return flag;
	}

	private static bool RewiredKeyDown(KeyCode key)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		if (!ReInput.isReady)
		{
			return false;
		}
		return ReInput.controllers.Keyboard.GetKeyDown(key);
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		nextSweepTime = Time.unscaledTime + 0.1f;
	}

	private void OnEnabledChanged()
	{
		if (ready)
		{
			if (cfgEnabled.Value)
			{
				Sweep();
			}
			else
			{
				RestoreOriginals();
			}
			PushGlobals(cfgEnabled.Value);
		}
	}

	private void PushGlobals(bool master)
	{
		//IL_0045: 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_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Invalid comparison between Unknown and I4
		//IL_00ab: 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_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		Shader.SetGlobalVector(SnapParamsId, new Vector4((float)cfgGridWidth.Value, (float)cfgGridHeight.Value, master ? 1f : 0f, cfgDepthCorrection.Value ? 1f : 0f));
		Shader.SetGlobalVector(SnapParams2Id, new Vector4(cfgOverlayBias.Value, (master && cfgAffineEnabled.Value) ? cfgAffineStrength.Value : 0f, 0f, 0f));
		Color val = cfgFogColor.Value;
		if ((int)QualitySettings.activeColorSpace == 1)
		{
			val = ((Color)(ref val)).linear;
		}
		Shader.SetGlobalVector(FogParamsId, new Vector4((master && cfgFogEnabled.Value) ? 1f : 0f, cfgFogStart.Value, Mathf.Max(cfgFogEnd.Value, cfgFogStart.Value + 0.01f), 0f));
		Shader.SetGlobalVector(FogColorId, new Vector4(val.r, val.g, val.b, 1f));
	}

	private void UpdatePostEffect(bool master)
	{
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		bool flag = master && cfgColorEnabled.Value && (Object)(object)colorDepthMaterial != (Object)null;
		if (flag)
		{
			float num = Mathf.Pow(2f, (float)cfgColorBits.Value) - 1f;
			colorDepthMaterial.SetVector(ColorParamsId, new Vector4(num, cfgDitherStrength.Value, (float)cfgDitherCell.Value, 0f));
		}
		for (int num2 = effects.Count - 1; num2 >= 0; num2--)
		{
			if ((Object)(object)effects[num2] == (Object)null)
			{
				effects.RemoveAt(num2);
			}
			else if (((Behaviour)effects[num2]).enabled != flag)
			{
				((Behaviour)effects[num2]).enabled = flag;
			}
		}
	}

	private void AttachPostEffects()
	{
		if ((Object)(object)colorDepthMaterial == (Object)null)
		{
			return;
		}
		Camera[] allCameras = Camera.allCameras;
		foreach (Camera val in allCameras)
		{
			if (!((Object)(object)val == (Object)null) && ((Behaviour)val).enabled && !((Object)(object)val.targetTexture != (Object)null) && ((Object)(object)val == (Object)(object)Camera.main || (Object)(object)((Component)val).GetComponent("PostProssesing") != (Object)null) && !((Object)(object)((Component)val).GetComponent<ColorDepthEffect>() != (Object)null))
			{
				ColorDepthEffect colorDepthEffect = ((Component)val).gameObject.AddComponent<ColorDepthEffect>();
				colorDepthEffect.EffectMaterial = colorDepthMaterial;
				effects.Add(colorDepthEffect);
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Color depth effect attached to camera: " + ((Object)val).name));
			}
		}
	}

	private void UpdateCharacterTextures(bool master)
	{
		bool flag = master && cfgPointFilter.Value;
		bool flag2 = flag && cfgNoMipmaps.Value;
		if (flag != texturesPoint || flag2 != texturesNoMips)
		{
			RestoreCharacterTextures();
			texturesPoint = flag;
			texturesNoMips = flag2;
			if (flag)
			{
				ApplyCharacterTextures();
			}
		}
	}

	private void ApplyCharacterTextures()
	{
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		foreach (Material characterMaterial in characterMaterials)
		{
			if ((Object)(object)characterMaterial == (Object)null)
			{
				continue;
			}
			string[] characterTextureProps = CharacterTextureProps;
			foreach (string text in characterTextureProps)
			{
				if (!characterMaterial.HasProperty(text))
				{
					continue;
				}
				Texture texture = characterMaterial.GetTexture(text);
				if (!((Object)(object)texture == (Object)null))
				{
					if (!textureOriginals.ContainsKey(texture))
					{
						textureOriginals[texture] = new TextureState
						{
							Filter = texture.filterMode,
							MipBias = texture.mipMapBias
						};
					}
					texture.filterMode = (FilterMode)0;
					if (texturesNoMips)
					{
						texture.mipMapBias = -16f;
					}
				}
			}
		}
	}

	private void RestoreCharacterTextures()
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		foreach (KeyValuePair<Texture, TextureState> textureOriginal in textureOriginals)
		{
			if ((Object)(object)textureOriginal.Key != (Object)null)
			{
				textureOriginal.Key.filterMode = textureOriginal.Value.Filter;
				textureOriginal.Key.mipMapBias = textureOriginal.Value.MipBias;
			}
		}
		textureOriginals.Clear();
	}

	private void Sweep()
	{
		nextSweepTime = Time.unscaledTime + cfgSweepInterval.Value;
		sweepCounter++;
		if (sweepCounter % 10 == 0)
		{
			PurgeDestroyed();
		}
		Material[] array = Resources.FindObjectsOfTypeAll<Material>();
		foreach (Material material in array)
		{
			PatchMaterial(material);
		}
		if (cfgApplyToUnrecognized.Value && (Object)(object)fallbackShader != (Object)null)
		{
			SweepFallback();
		}
		AttachPostEffects();
		if (texturesPoint)
		{
			ApplyCharacterTextures();
		}
	}

	private void PatchMaterial(Material material)
	{
		if ((Object)(object)material == (Object)null || (Object)(object)material.shader == (Object)null || originals.ContainsKey(material))
		{
			return;
		}
		string name = ((Object)material.shader).name;
		if (name.StartsWith("VertexSnap/"))
		{
			return;
		}
		if (replacements.TryGetValue(name, out var value))
		{
			originals[material] = material.shader;
			material.shader = value;
			if (name == "Reptile/Ambient Character")
			{
				characterMaterials.Add(material);
			}
		}
		else if (cfgLogUnrecognized.Value && reportedShaders.Add(name))
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Unrecognized shader (not patched): " + name));
		}
	}

	private void SweepFallback()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		Renderer[] array = Resources.FindObjectsOfTypeAll<Renderer>();
		foreach (Renderer val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Scene scene = ((Component)val).gameObject.scene;
			if (((Scene)(ref scene)).IsValid() && (val is MeshRenderer || val is SkinnedMeshRenderer))
			{
				Material[] sharedMaterials = val.sharedMaterials;
				foreach (Material material in sharedMaterials)
				{
					TryFallback(material);
				}
			}
		}
	}

	private void TryFallback(Material material)
	{
		if ((Object)(object)material == (Object)null || (Object)(object)material.shader == (Object)null || originals.ContainsKey(material))
		{
			return;
		}
		string name = ((Object)material.shader).name;
		if (name.StartsWith("VertexSnap/") || replacements.ContainsKey(name))
		{
			return;
		}
		string[] fallbackBlockedPrefixes = FallbackBlockedPrefixes;
		foreach (string value in fallbackBlockedPrefixes)
		{
			if (name.StartsWith(value))
			{
				return;
			}
		}
		if (material.HasProperty("_MainTex") && material.renderQueue <= 2450)
		{
			originals[material] = material.shader;
			material.shader = fallbackShader;
		}
	}

	private void RestoreOriginals()
	{
		foreach (KeyValuePair<Material, Shader> original in originals)
		{
			if ((Object)(object)original.Key != (Object)null && (Object)(object)original.Value != (Object)null)
			{
				original.Key.shader = original.Value;
			}
		}
		originals.Clear();
	}

	private void PurgeDestroyed()
	{
		List<Material> list = new List<Material>();
		foreach (Material key in originals.Keys)
		{
			if ((Object)(object)key == (Object)null)
			{
				list.Add(key);
			}
		}
		foreach (Material item in list)
		{
			originals.Remove(item);
		}
		characterMaterials.RemoveWhere((Material material) => (Object)(object)material == (Object)null);
	}

	private void OnDestroy()
	{
		//IL_0068: 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_0086: Unknown result type (might be due to invalid IL or missing references)
		SceneManager.sceneLoaded -= OnSceneLoaded;
		if (ready)
		{
			RestoreOriginals();
			RestoreCharacterTextures();
			foreach (ColorDepthEffect effect in effects)
			{
				if ((Object)(object)effect != (Object)null)
				{
					Object.Destroy((Object)(object)effect);
				}
			}
			Shader.SetGlobalVector(SnapParamsId, Vector4.zero);
			Shader.SetGlobalVector(SnapParams2Id, Vector4.zero);
			Shader.SetGlobalVector(FogParamsId, Vector4.zero);
		}
		if ((Object)(object)colorDepthMaterial != (Object)null)
		{
			Object.Destroy((Object)(object)colorDepthMaterial);
		}
		if ((Object)(object)bundle != (Object)null)
		{
			bundle.Unload(false);
		}
	}
}