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 + "'"));
}
}
}
}
}