Decompiled source of Leech VFX Remover v1.0.2

plugins/LeechVFXRemover.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LeechVFXRemover")]
[assembly: AssemblyDescription("A simple yet powerful mod that removes the leech VFX from Valheim., thus greatly improving performance in areas with many leeches, such as the Swamps.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("proflupin")]
[assembly: AssemblyProduct("LeechVFXRemover")]
[assembly: AssemblyCopyright("Copyright © proflupin 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7e61f470-fb41-4c6b-a654-4e199ea7d009")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
namespace LeechVFXRemover;

[BepInPlugin("com.proflupin.leechvfxremover", "LeechVFXRemover", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class JotunnModStub : BaseUnityPlugin
{
	public const string PluginGUID = "com.proflupin.leechvfxremover";

	public const string PluginName = "LeechVFXRemover";

	public const string PluginVersion = "1.0.1";

	public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

	private ConfigEntry<bool> DisableParticleSystems;

	private ConfigEntry<bool> DisableTrailRenderers;

	private ConfigEntry<bool> DisableVisualEffects;

	private ConfigEntry<bool> DisableLights;

	private ConfigEntry<bool> DisableNamedVfxObjects;

	private void Awake()
	{
		Logger.LogInfo((object)"Leech VFX Remover: initializing");
		DisableParticleSystems = ((BaseUnityPlugin)this).Config.Bind<bool>("VFX Categories", "DisableParticleSystems", true, "Disable particle system effects on the Leech");
		DisableTrailRenderers = ((BaseUnityPlugin)this).Config.Bind<bool>("VFX Categories", "DisableTrailRenderers", true, "Disable trail renderer effects on the Leech");
		DisableVisualEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("VFX Categories", "DisableVisualEffects", true, "Disable Visual Effect Graph effects on the Leech");
		DisableLights = ((BaseUnityPlugin)this).Config.Bind<bool>("VFX Categories", "DisableLights", true, "Disable light components on the Leech");
		DisableNamedVfxObjects = ((BaseUnityPlugin)this).Config.Bind<bool>("VFX Categories", "DisableNamedVfxObjects", true, "Disable GameObjects with VFX-related names (vfx_, fx_, effect_, etc.)");
		((MonoBehaviour)this).StartCoroutine(WaitAndPatchLeech());
	}

	private IEnumerator WaitAndPatchLeech()
	{
		yield return (object)new WaitUntil((Func<bool>)(() => Resources.FindObjectsOfTypeAll<GameObject>().Length != 0));
		GameObject leech = null;
		for (int i = 0; i < 10; i++)
		{
			if (!((Object)(object)leech == (Object)null))
			{
				break;
			}
			GameObject[] all = Resources.FindObjectsOfTypeAll<GameObject>();
			GameObject[] array = all;
			foreach (GameObject go in array)
			{
				if ((Object)(object)go != (Object)null && ((Object)go).name == "Leech")
				{
					leech = go;
					break;
				}
			}
			if ((Object)(object)leech == (Object)null)
			{
				yield return (object)new WaitForSeconds(0.5f);
			}
		}
		if ((Object)(object)leech == (Object)null)
		{
			Logger.LogWarning((object)"Leech VFX Remover: Leech prefab not found");
			yield break;
		}
		if (!DisableParticleSystems.Value && !DisableTrailRenderers.Value && !DisableVisualEffects.Value && !DisableLights.Value && !DisableNamedVfxObjects.Value)
		{
			Logger.LogInfo((object)"Leech VFX Remover: all VFX categories disabled by config");
			yield break;
		}
		try
		{
			RemoveLeechVfx(leech);
			Logger.LogInfo((object)"Leech VFX Remover: applied to Leech prefab");
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("Leech VFX Remover: failed to patch Leech prefab: " + ex));
		}
	}

	private void RemoveLeechVfx(GameObject leechPrefab)
	{
		//IL_0397: Unknown result type (might be due to invalid IL or missing references)
		//IL_039c: Unknown result type (might be due to invalid IL or missing references)
		List<Transform> list = new List<Transform>();
		leechPrefab.GetComponentsInChildren<Transform>(true, list);
		string[] source = new string[14]
		{
			"vfx_", "fx_", "effect_", "particle_", "splash", "ripple", "bubble", "water_", "wet_", "drip",
			"spray", "trail", "glow", "shine"
		};
		string[] source2 = new string[11]
		{
			"attack", "damage", "collision", "trigger", "hitbox", "body", "mesh", "model", "skeleton", "bone",
			"root"
		};
		foreach (Transform item in list)
		{
			if ((Object)(object)item == (Object)null || !((Component)item).gameObject.activeSelf)
			{
				continue;
			}
			string objName = ((Object)item).name.ToLowerInvariant();
			if (!source2.Any((string p) => objName.Contains(p)))
			{
				bool flag = false;
				if (DisableNamedVfxObjects.Value && source.Any((string p) => objName.Contains(p)))
				{
					flag = true;
				}
				bool flag2 = DisableParticleSystems.Value && (Object)(object)((Component)item).GetComponent<ParticleSystem>() != (Object)null;
				bool flag3 = DisableTrailRenderers.Value && (Object)(object)((Component)item).GetComponent<TrailRenderer>() != (Object)null;
				bool flag4 = DisableVisualEffects.Value && (Object)(object)((Component)item).GetComponent(Type.GetType("UnityEngine.VFX.VisualEffect, UnityEngine.VFXModule")) != (Object)null;
				bool flag5 = DisableLights.Value && (Object)(object)((Component)item).GetComponent<Light>() != (Object)null;
				if (flag2 || flag3 || flag4 || flag5)
				{
					flag = true;
				}
				if (flag)
				{
					Logger.LogInfo((object)("Leech VFX Remover: disabling VFX object '" + objName + "' with components [" + (flag2 ? "Particles " : "") + (flag3 ? "Trail " : "") + (flag4 ? "VFX " : "") + (flag5 ? "Light" : "") + "]"));
					((Component)item).gameObject.SetActive(false);
				}
			}
		}
		if (DisableParticleSystems.Value)
		{
			ParticleSystem[] componentsInChildren = leechPrefab.GetComponentsInChildren<ParticleSystem>(true);
			ParticleSystem[] array = componentsInChildren;
			foreach (ParticleSystem val in array)
			{
				if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeSelf)
				{
					continue;
				}
				Transform parent = ((Component)val).transform.parent;
				string parentName4 = ((parent != null) ? ((Object)parent).name.ToLowerInvariant() : null) ?? "";
				if (!source2.Any((string p) => parentName4.Contains(p)))
				{
					try
					{
						EmissionModule emission = val.emission;
						((EmissionModule)(ref emission)).enabled = false;
						val.Stop(true, (ParticleSystemStopBehavior)1);
						Logger.LogInfo((object)("Leech VFX Remover: disabled ParticleSystem emission on '" + ((Object)((Component)val).gameObject).name + "'"));
					}
					catch
					{
					}
				}
			}
		}
		if (DisableVisualEffects.Value)
		{
			Type type = Type.GetType("UnityEngine.VFX.VisualEffect, UnityEngine.VFXModule");
			if (type != null)
			{
				Component[] componentsInChildren2 = leechPrefab.GetComponentsInChildren(type, true);
				Component[] array2 = componentsInChildren2;
				foreach (Component val2 in array2)
				{
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					Component val3 = val2;
					if (!((Object)(object)val3 != (Object)null) || !val3.gameObject.activeSelf)
					{
						continue;
					}
					Behaviour val4 = (Behaviour)(object)((val3 is Behaviour) ? val3 : null);
					if ((Object)(object)val4 != (Object)null)
					{
						Transform parent2 = val3.transform.parent;
						string parentName3 = ((parent2 != null) ? ((Object)parent2).name.ToLowerInvariant() : null) ?? "";
						if (!source2.Any((string p) => parentName3.Contains(p)))
						{
							val4.enabled = false;
							Logger.LogInfo((object)("Leech VFX Remover: disabled VisualEffect on '" + ((Object)val3.gameObject).name + "'"));
						}
					}
				}
			}
		}
		if (DisableTrailRenderers.Value)
		{
			TrailRenderer[] componentsInChildren3 = leechPrefab.GetComponentsInChildren<TrailRenderer>(true);
			TrailRenderer[] array3 = componentsInChildren3;
			foreach (TrailRenderer val5 in array3)
			{
				if (!((Object)(object)val5 == (Object)null) && ((Component)val5).gameObject.activeSelf)
				{
					Transform parent3 = ((Component)val5).transform.parent;
					string parentName2 = ((parent3 != null) ? ((Object)parent3).name.ToLowerInvariant() : null) ?? "";
					if (!source2.Any((string p) => parentName2.Contains(p)))
					{
						((Renderer)val5).enabled = false;
						Logger.LogInfo((object)("Leech VFX Remover: disabled TrailRenderer on '" + ((Object)((Component)val5).gameObject).name + "'"));
					}
				}
			}
		}
		if (!DisableLights.Value)
		{
			return;
		}
		Light[] componentsInChildren4 = leechPrefab.GetComponentsInChildren<Light>(true);
		Light[] array4 = componentsInChildren4;
		foreach (Light val6 in array4)
		{
			if (!((Object)(object)val6 == (Object)null) && ((Component)val6).gameObject.activeSelf)
			{
				Transform parent4 = ((Component)val6).transform.parent;
				string parentName = ((parent4 != null) ? ((Object)parent4).name.ToLowerInvariant() : null) ?? "";
				if (!source2.Any((string p) => parentName.Contains(p)))
				{
					((Behaviour)val6).enabled = false;
					Logger.LogInfo((object)("Leech VFX Remover: disabled Light on '" + ((Object)((Component)val6).gameObject).name + "'"));
				}
			}
		}
	}
}