Decompiled source of HueShifter v1.0.0

HueShifter.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using GlobalEnums;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Silksong.DataManager;
using Silksong.ModMenu.Elements;
using Silksong.ModMenu.Models;
using Silksong.ModMenu.Plugin;
using Silksong.ModMenu.Screens;
using UnityEngine;
using UnityEngine.SceneManagement;

[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("HueShifter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2d784e5b8b781b78773e4ca964b27398601a2f0e")]
[assembly: AssemblyProduct("HueShifter")]
[assembly: AssemblyTitle("HueShifter")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dpinela/HueShifter")]
[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 MonoDetour.HookGen
{
	internal static class DefaultMonoDetourManager
	{
		internal static MonoDetourManager Instance { get; } = New();


		internal static MonoDetourManager New()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			return new MonoDetourManager(typeof(DefaultMonoDetourManager).Assembly.GetName().Name);
		}
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
	internal class MonoDetourTargetsAttribute : Attribute, IMonoDetourTargets
	{
		public Type? TargetType { get; }

		public bool IncludeNestedTypes { get; set; }

		public bool DistinguishOverloadsByName { get; set; }

		public string[]? Members { get; set; }

		public string[]? MemberNamePrefixes { get; set; }

		public string[]? MemberNameSuffixes { get; set; }

		public bool GenerateControlFlowVariants { get; set; }

		public MonoDetourTargetsAttribute(Type? targetType = null)
		{
			TargetType = targetType;
			IncludeNestedTypes = true;
			base..ctor();
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace HueShifter
{
	[HarmonyPatch(typeof(SceneColorManager), "UpdateScriptParameters")]
	internal static class HeroLightHandler
	{
		private static void Postfix()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (HueShifterPlugin.Instance.GS.ModEnabled && (Object)(object)HeroController.instance != (Object)null)
			{
				float num = default(float);
				float num2 = default(float);
				float num3 = default(float);
				Color.RGBToHSV(HeroController.instance.heroLight.BaseColor, ref num, ref num2, ref num3);
				HeroController.instance.heroLight.BaseColor = Color.HSVToRGB(Mathf.Repeat(num + HueShifterPlugin.Instance.GetPhase(), 1f), num2, num3);
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("io.github.dpinela.hueshifter", "HueShifter", "1.0.0")]
	public class HueShifterPlugin : BaseUnityPlugin, IModMenuCustomMenu, IModMenuInterface, IProfileDataMod<HueShifterSettings>, IProfileDataMod
	{
		[HarmonyPatch(typeof(GameManager), "OnNextLevelReady")]
		private static class NextLevelPatch
		{
			[CompilerGenerated]
			private sealed class <<Postfix>g__DelayedShaderSet|0_0>d : IEnumerator<object>, IEnumerator, IDisposable
			{
				private int <>1__state;

				private object <>2__current;

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

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

				[DebuggerHidden]
				public <<Postfix>g__DelayedShaderSet|0_0>d(int <>1__state)
				{
					this.<>1__state = <>1__state;
				}

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

				private bool MoveNext()
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = null;
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						Instance.SetAllTheShaders();
						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 void Postfix(GameManager __instance)
			{
				if (Instance.GS.ModEnabled)
				{
					((MonoBehaviour)__instance).StartCoroutine(DelayedShaderSet());
				}
				[IteratorStateMachine(typeof(<<Postfix>g__DelayedShaderSet|0_0>d))]
				static IEnumerator DelayedShaderSet()
				{
					//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
					return new <<Postfix>g__DelayedShaderSet|0_0>d(0);
				}
			}
		}

		public static HueShifterPlugin Instance;

		[CompilerGenerated]
		private HueShifterSettings? <ProfileData>k__BackingField = new HueShifterSettings();

		public Shader RainbowDefault;

		public Shader RainbowScreenBlend;

		public Shader RainbowLit;

		public Shader RainbowParticleAdd;

		public Shader RainbowParticleAddSoft;

		public Shader RainbowGrassDefault;

		public Shader RainbowGrassLit;

		public readonly Dictionary<string, float> Palette = new Dictionary<string, float>();

		internal readonly MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();

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

		private static readonly int PhaseProperty = Shader.PropertyToID("_Phase");

		private static readonly int FrequencyProperty = Shader.PropertyToID("_Frequency");

		private const string MenuName = "HueShifter";

		public const string Id = "io.github.dpinela.hueshifter";

		public HueShifterSettings? ProfileData
		{
			[CompilerGenerated]
			get
			{
				return <ProfileData>k__BackingField;
			}
			set
			{
				<ProfileData>k__BackingField = ((value != null) ? value : new HueShifterSettings());
			}
		}

		internal HueShifterSettings GS => ProfileData;

		public bool ToggleButtonInsideMenu => true;

		public static string Name => "HueShifter";

		public static string Version => "1.0.0";

		public void LoadAssets()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0008: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			RuntimePlatform platform = Application.platform;
			string text;
			if ((int)platform != 1)
			{
				if ((int)platform != 2)
				{
					if ((int)platform != 13)
					{
						throw new PlatformNotSupportedException("What platform are you even on??");
					}
					text = "linux";
				}
				else
				{
					text = "windows";
				}
			}
			else
			{
				text = "osx";
			}
			string text2 = text;
			AssetBundle val = AssetBundle.LoadFromStream(typeof(HueShifterPlugin).Assembly.GetManifestResourceStream("HueShifter.Resources.AssetBundles.hueshiftshaders-" + text2));
			RainbowDefault = val.LoadAsset<Shader>("assets/shader/rainbowdefault.shader");
			RainbowScreenBlend = val.LoadAsset<Shader>("assets/shader/rainbowscreenblend.shader");
			RainbowLit = val.LoadAsset<Shader>("assets/shader/rainbowlit.shader");
			RainbowParticleAdd = val.LoadAsset<Shader>("assets/shader/rainbowparticleadd.shader");
			RainbowParticleAddSoft = val.LoadAsset<Shader>("assets/shader/rainbowparticleaddsoft.shader");
			RainbowGrassDefault = val.LoadAsset<Shader>("assets/shader/rainbowgrassdefault.shader");
			RainbowGrassLit = val.LoadAsset<Shader>("assets/shader/rainbowgrasslit.shader");
		}

		public void Start()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			if (RainbowDefault == null)
			{
				LoadAssets();
			}
			new Harmony("io.github.dpinela.hueshifter").PatchAll();
		}

		public float GetPhase()
		{
			string key;
			switch (GS.RandomPhase)
			{
			case RandomPhaseSetting.RandomPerMapArea:
				key = ((object)(MapZone)(ref GameManager.instance.sm.mapZone)).ToString();
				break;
			case RandomPhaseSetting.RandomPerRoom:
				key = GameManager.instance.sceneName;
				break;
			default:
				return GS.Phase / 360f;
			}
			if (!Palette.ContainsKey(key))
			{
				Palette[key] = (GS.AllowVanillaPhase ? Random.Range(0f, 1f) : Random.Range(0.05f, 0.95f));
			}
			return Palette[key];
		}

		private void SetAllTheShaders()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			Vector4 frequencyVector = default(Vector4);
			((Vector4)(ref frequencyVector))..ctor(GS.XFrequency / 40f, GS.YFrequency / 40f, GS.ZFrequency / 200f, GS.TimeFrequency / 10f);
			float phase = GetPhase();
			Renderer[] componentsInChildren;
			for (int i = 0; i < SceneManager.sceneCount; i++)
			{
				Scene sceneAt = SceneManager.GetSceneAt(i);
				if (GameManager.GetBaseSceneName(((Scene)(ref sceneAt)).name) != GameManager.instance.sceneName)
				{
					continue;
				}
				GameObject[] rootGameObjects = ((Scene)(ref sceneAt)).GetRootGameObjects();
				for (int j = 0; j < rootGameObjects.Length; j++)
				{
					componentsInChildren = rootGameObjects[j].GetComponentsInChildren<Renderer>(true);
					foreach (Renderer renderer in componentsInChildren)
					{
						if (ShouldShift(renderer))
						{
							SetShader(renderer, phase, frequencyVector);
						}
					}
				}
			}
			componentsInChildren = ((Component)GameCameras.instance.sceneParticles).GetComponentsInChildren<Renderer>(false);
			foreach (Renderer val in componentsInChildren)
			{
				if (val.enabled)
				{
					SetShader(val, phase, frequencyVector);
				}
			}
			materialSwaps.Clear();
		}

		public static bool ShouldShift(Renderer renderer)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)renderer).gameObject;
			SpriteRenderer val = (SpriteRenderer)(object)((renderer is SpriteRenderer) ? renderer : null);
			if (val != null)
			{
				Color color = val.color;
				if (((Color)(ref color)).maxColorComponent == 0f)
				{
					return false;
				}
			}
			return ((Object)gameObject).name != "Item Sprite";
		}

		public void SetShader(Renderer renderer, float phase, Vector4 frequencyVector)
		{
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			Material[] sharedMaterials = renderer.sharedMaterials;
			for (int i = 0; i < sharedMaterials.Length; i++)
			{
				Material val = sharedMaterials[i];
				if (val == null)
				{
					continue;
				}
				bool flag2;
				switch (((Object)val.shader).name)
				{
				case "Custom/RainbowParticleAdd":
				case "Custom/RainbowScreenBlend":
				case "Custom/RainbowLit":
				case "Custom/RainbowDefault":
				case "Custom/RainbowParticleAddSoft":
				case "Custom/RainbowGrassDefault":
				case "Custom/RainbowGrassLit":
					flag2 = true;
					break;
				default:
					flag2 = false;
					break;
				}
				if (flag2)
				{
					flag = true;
					continue;
				}
				if (!materialSwaps.ContainsKey(val))
				{
					Shader val2 = (Shader)(((Object)val.shader).name switch
					{
						"Sprites/Lit" => GS.RespectLighting ? RainbowLit : RainbowDefault, 
						"Sprites/Default" => RainbowDefault, 
						"Sprites/Cherry-Default" => RainbowDefault, 
						"UI/BlendModes/Screen" => RainbowScreenBlend, 
						"Sprites/Screen" => RainbowScreenBlend, 
						"Legacy Shaders/Particles/Additive" => RainbowParticleAdd, 
						"Legacy Shaders/Particles/Additive (Soft)" => RainbowParticleAddSoft, 
						"Hollow Knight/Grass-Default" => RainbowGrassDefault, 
						"Hollow Knight/Grass-Diffuse" => GS.RespectLighting ? RainbowGrassLit : RainbowGrassDefault, 
						_ => null, 
					});
					if (val2 == null)
					{
						continue;
					}
					Material val3 = Object.Instantiate<Material>(val);
					val3.shader = val2;
					materialSwaps[val] = val3;
				}
				flag = true;
				sharedMaterials[i] = materialSwaps[val];
			}
			if (flag)
			{
				renderer.sharedMaterials = sharedMaterials;
				renderer.GetPropertyBlock(materialPropertyBlock);
				materialPropertyBlock.SetFloat(PhaseProperty, phase);
				materialPropertyBlock.SetVector(FrequencyProperty, frequencyVector);
				renderer.SetPropertyBlock(materialPropertyBlock);
			}
		}

		public string ModMenuName()
		{
			return "HueShifter";
		}

		public AbstractMenuScreen BuildCustomMenu()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Expected O, but got Unknown
			PaginatedMenuScreen val = new PaginatedMenuScreen("HueShifter");
			VerticalGroup val2 = new VerticalGroup();
			Action refreshMenu = delegate
			{
			};
			val2.Add((IMenuEntity)(object)Toggle("Mod Enabled", () => GS.ModEnabled, delegate(bool v)
			{
				GS.ModEnabled = v;
			}, ref refreshMenu));
			ListChoiceModel<RandomPhaseSetting> model = ChoiceModels.ForEnum<RandomPhaseSetting>();
			((AbstractValueModel<RandomPhaseSetting>)(object)model).OnValueChanged += delegate(RandomPhaseSetting ps)
			{
				GS.RandomPhase = ps;
			};
			refreshMenu = (Action)Delegate.Combine(refreshMenu, (Action)delegate
			{
				((AbstractValueModel<RandomPhaseSetting>)(object)model).SetValue(GS.RandomPhase);
			});
			val2.Add((IMenuEntity)(object)new ChoiceElement<RandomPhaseSetting>("Randomize Hues", (IChoiceModel<RandomPhaseSetting>)(object)model, ""));
			val2.Add((IMenuEntity)(object)Slider("Hue Shift Angle", 0f, 360f, 37, () => GS.Phase, delegate(float v)
			{
				GS.Phase = v;
			}, ref refreshMenu));
			val2.Add((IMenuEntity)(object)Toggle("Allow Vanilla Colours", () => GS.AllowVanillaPhase, delegate(bool v)
			{
				GS.AllowVanillaPhase = v;
			}, ref refreshMenu));
			val2.Add((IMenuEntity)(object)Toggle("Respect Lighting", () => GS.RespectLighting, delegate(bool v)
			{
				GS.RespectLighting = v;
			}, ref refreshMenu));
			val2.Add((IMenuEntity)(object)Button("Re-roll Palette", delegate
			{
				Palette.Clear();
				SetAllTheShaders();
			}));
			val.AddPage((INavigableMenuEntity)(object)val2);
			VerticalGroup val3 = new VerticalGroup();
			val3.Add((IMenuEntity)(object)Slider("Rainbow Y", -100f, 100f, 21, () => GS.YFrequency, delegate(float v)
			{
				GS.YFrequency = v;
			}, ref refreshMenu));
			val3.Add((IMenuEntity)(object)Slider("Rainbow Z", -100f, 100f, 21, () => GS.ZFrequency, delegate(float v)
			{
				GS.ZFrequency = v;
			}, ref refreshMenu));
			val3.Add((IMenuEntity)(object)Slider("Rainbow X", -100f, 100f, 21, () => GS.XFrequency, delegate(float v)
			{
				GS.XFrequency = v;
			}, ref refreshMenu));
			val3.Add((IMenuEntity)(object)Slider("Animation Speed", -100f, 100f, 21, () => GS.TimeFrequency, delegate(float v)
			{
				GS.TimeFrequency = v;
			}, ref refreshMenu));
			val3.Add((IMenuEntity)(object)Button("Apply to Current Room", SetAllTheShaders));
			val3.Add((IMenuEntity)(object)Button("Reset to Defaults", delegate
			{
				ProfileData = new HueShifterSettings();
				refreshMenu();
				SetAllTheShaders();
			}));
			val.AddPage((INavigableMenuEntity)(object)val3);
			refreshMenu();
			return (AbstractMenuScreen)val;
		}

		private static ChoiceElement<bool> Toggle(string label, Func<bool> getter, Action<bool> setter, ref Action refresh)
		{
			Func<bool> getter2 = getter;
			ListChoiceModel<bool> model = ChoiceModels.ForBool("Off", "On");
			((AbstractValueModel<bool>)(object)model).OnValueChanged += setter;
			refresh = (Action)Delegate.Combine(refresh, (Action)delegate
			{
				((AbstractValueModel<bool>)(object)model).SetValue(getter2());
			});
			return new ChoiceElement<bool>(label, (IChoiceModel<bool>)(object)model, "");
		}

		private static SliderElement<float> Slider(string label, float min, float max, int numSteps, Func<float> getter, Action<float> setter, ref Action refresh)
		{
			Func<float> getter2 = getter;
			LinearFloatSliderModel model = SliderModels.ForFloats(min, max, numSteps);
			((AbstractValueModel<float>)(object)model).OnValueChanged += setter;
			refresh = (Action)Delegate.Combine(refresh, (Action)delegate
			{
				((AbstractValueModel<float>)(object)model).SetValue(getter2());
			});
			return new SliderElement<float>(label, (SliderModel<float>)(object)model);
		}

		private static TextButton Button(string label, Action effect)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			TextButton val = new TextButton(label);
			val.OnSubmit = (Action)Delegate.Combine(val.OnSubmit, effect);
			return val;
		}
	}
	public enum RandomPhaseSetting
	{
		Fixed,
		RandomPerMapArea,
		RandomPerRoom
	}
	public class HueShifterSettings
	{
		public bool ModEnabled = true;

		public float Phase;

		public RandomPhaseSetting RandomPhase = RandomPhaseSetting.RandomPerMapArea;

		public bool RespectLighting = true;

		public float XFrequency;

		public float YFrequency;

		public float ZFrequency;

		public float TimeFrequency;

		public bool AllowVanillaPhase;
	}
}