Decompiled source of StaffProtectionBubbleRemover v2.0.0

plugins/StaffProtectionBubbleRemover.dll

Decompiled a month 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 System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("StaffProtectionBubbleRemover")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Removes the visual bubble effect from Staff of Protection while keeping its protective functionality")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("StaffProtectionBubbleRemover")]
[assembly: AssemblyTitle("StaffProtectionBubbleRemover")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace StaffProtectionBubbleRemover
{
	[BepInPlugin("Caldor.StaffProtectionBubbleRemover", "StaffProtectionBubbleRemover", "2.0.0")]
	public class StaffProtectionBubbleRemoverPlugin : BaseUnityPlugin
	{
		internal const string ModName = "StaffProtectionBubbleRemover";

		internal const string ModVersion = "2.0.0";

		internal const string Author = "Caldor";

		private const string ModGUID = "Caldor.StaffProtectionBubbleRemover";

		private static readonly Harmony harmony = new Harmony("Caldor.StaffProtectionBubbleRemover");

		public static ManualLogSource StaffProtectionBubbleRemoverLogger;

		private static string logFilePath;

		private static StreamWriter logWriter;

		internal static HashSet<string> processedEffects = new HashSet<string>();

		private static bool configurationManagerDetected = false;

		public static ConfigEntry<bool> ModEnabled;

		public static ConfigEntry<bool> EnableDebugLogging;

		public static ConfigEntry<bool> DisableStaffShieldVfx;

		public static ConfigEntry<bool> DisableCentralOrb;

		public static ConfigEntry<bool> DisableDroppingOrb;

		public static ConfigEntry<bool> DisableFxShieldStart;

		private void Awake()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			StaffProtectionBubbleRemoverLogger = ((BaseUnityPlugin)this).Logger;
			DetectConfigurationManager();
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Mod Enabled", true, new ConfigDescription("Enable/disable the entire mod", (AcceptableValueBase)null, Array.Empty<object>()));
			string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "StaffProtectionBubbleRemover");
			string text2 = "Enable debug logging to file (impacts performance).\nLogs saved to: " + text;
			if (!configurationManagerDetected)
			{
				text2 += "\n\nTip: Install Configuration Manager for easier in-game configuration!";
			}
			EnableDebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Debug", "Enable Debug Logging", false, new ConfigDescription(text2, (AcceptableValueBase)null, Array.Empty<object>()));
			DisableStaffShieldVfx = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Visual Effects", "Disable Staff Shield VFX", true, new ConfigDescription("Disable vfx_StaffShield(Clone) - the main staff shield sphere visual", (AcceptableValueBase)null, Array.Empty<object>()));
			DisableCentralOrb = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Visual Effects", "Disable Central Orb", true, new ConfigDescription("Disable Central Orb - the glowing orb effect", (AcceptableValueBase)null, Array.Empty<object>()));
			DisableDroppingOrb = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Visual Effects", "Disable Dropping Orb", false, new ConfigDescription("Disable Dropping Orb - the falling orb particle effect", (AcceptableValueBase)null, Array.Empty<object>()));
			DisableFxShieldStart = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Visual Effects", "Disable Shield Start FX", true, new ConfigDescription("Disable fx_shield_start(Clone) - the shield activation effects", (AcceptableValueBase)null, Array.Empty<object>()));
			if (EnableDebugLogging.Value)
			{
				Directory.CreateDirectory(text);
				logFilePath = Path.Combine(text, $"debug_log_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.txt");
				try
				{
					logWriter = new StreamWriter(logFilePath, append: true);
					LogToFile("=== Staff Protection Bubble Remover Debug Log Started ===");
					LogToFile($"Time: {DateTime.Now}");
					LogToFile("Valheim Session Started");
					LogToFile("=============================================================");
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failed to create log file: " + ex.Message));
				}
			}
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Caldor.StaffProtectionBubbleRemover is loaded!");
			if (EnableDebugLogging.Value)
			{
				LogToFile("Plugin Caldor.StaffProtectionBubbleRemover is loaded!");
			}
			if (configurationManagerDetected)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Configuration Manager detected - settings available via F1 key");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Configuration Manager not detected - settings available via config file");
			}
		}

		private void DetectConfigurationManager()
		{
			try
			{
				Type type = Type.GetType("ConfigurationManager.ConfigurationManager, ConfigurationManager");
				Type type2 = Type.GetType("ConfigurationManager.ConfigurationManager, BepInEx.ConfigurationManager");
				configurationManagerDetected = type != null || type2 != null;
				if (configurationManagerDetected)
				{
					string text = ((type != null) ? "shudnal's" : "official BepInEx");
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Configuration Manager detected: " + text + " version"));
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Error detecting Configuration Manager: " + ex.Message));
				configurationManagerDetected = false;
			}
		}

		private void OnDestroy()
		{
			if (EnableDebugLogging.Value)
			{
				LogToFile("Plugin unloading...");
			}
			if (logWriter != null)
			{
				logWriter.Close();
				logWriter.Dispose();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Caldor.StaffProtectionBubbleRemover is unloaded!");
		}

		public static void LogToFile(string message)
		{
			if (!EnableDebugLogging.Value)
			{
				return;
			}
			try
			{
				if (logWriter != null)
				{
					string text = DateTime.Now.ToString("HH:mm:ss.fff");
					logWriter.WriteLine("[" + text + "] " + message);
					logWriter.Flush();
				}
			}
			catch (Exception ex)
			{
				if (StaffProtectionBubbleRemoverLogger != null)
				{
					StaffProtectionBubbleRemoverLogger.LogError((object)("Failed to write to log file: " + ex.Message));
				}
			}
		}

		public static void LogBoth(string message)
		{
			if (EnableDebugLogging.Value)
			{
				StaffProtectionBubbleRemoverLogger.LogInfo((object)message);
				LogToFile(message);
			}
		}
	}
	[HarmonyPatch(typeof(StatusEffect))]
	public static class StatusEffect_Patch
	{
		[HarmonyPatch("Setup")]
		[HarmonyPostfix]
		private static void Setup_Postfix(StatusEffect __instance, Character character)
		{
			if (!StaffProtectionBubbleRemoverPlugin.ModEnabled.Value || __instance.m_name == null)
			{
				return;
			}
			StaffProtectionBubbleRemoverPlugin.LogBoth("StatusEffect Setup called for: " + __instance.m_name + " (Type: " + ((object)__instance).GetType().Name + ")");
			if (__instance.m_name.ToLower().Contains("shield"))
			{
				string item = $"{((Object)character).GetInstanceID()}_{__instance.m_name}";
				if (!StaffProtectionBubbleRemoverPlugin.processedEffects.Contains(item))
				{
					StaffProtectionBubbleRemoverPlugin.processedEffects.Add(item);
					StaffProtectionBubbleRemoverPlugin.LogBoth("Found shield effect: " + __instance.m_name);
					DisableSpecificEffects(character);
				}
			}
		}

		private static void DisableSpecificEffects(Character character)
		{
			if (!((Object)(object)character == (Object)null))
			{
				StaffProtectionBubbleRemoverPlugin.LogBoth("=== DISABLING SPECIFIC EFFECTS FOR " + ((Object)character).name + " ===");
				if (StaffProtectionBubbleRemoverPlugin.EnableDebugLogging.Value)
				{
					LogAllChildTransforms(((Component)character).transform, "");
				}
				DisableSpecificEffectByName(((Component)character).transform, "vfx_StaffShield(Clone)", StaffProtectionBubbleRemoverPlugin.DisableStaffShieldVfx.Value);
				DisableSpecificEffectByName(((Component)character).transform, "fx_shield_start(Clone)", StaffProtectionBubbleRemoverPlugin.DisableFxShieldStart.Value);
				Transform val = ((Component)character).transform.Find("fx_shield_start(Clone)");
				if ((Object)(object)val != (Object)null)
				{
					DisableSpecificEffectByName(val, "Central Orb", StaffProtectionBubbleRemoverPlugin.DisableCentralOrb.Value);
					DisableSpecificEffectByName(val, "Dropping Orb", StaffProtectionBubbleRemoverPlugin.DisableDroppingOrb.Value);
				}
			}
		}

		private static void LogAllChildTransforms(Transform parent, string indent)
		{
			StaffProtectionBubbleRemoverPlugin.LogBoth($"{indent}{((Object)parent).name} - Active: {((Component)parent).gameObject.activeSelf}");
			Component[] components = ((Component)parent).GetComponents<Component>();
			foreach (Component val in components)
			{
				Renderer val2 = (Renderer)(object)((val is Renderer) ? val : null);
				if (val2 != null)
				{
					StaffProtectionBubbleRemoverPlugin.LogBoth($"{indent}  -> Renderer: {((object)val2).GetType().Name}, Enabled: {val2.enabled}");
					if ((Object)(object)val2.material != (Object)null)
					{
						StaffProtectionBubbleRemoverPlugin.LogBoth(indent + "     Material: " + ((Object)val2.material).name + ", Shader: " + ((Object)val2.material.shader).name);
					}
				}
				else if (val is ParticleSystem)
				{
					StaffProtectionBubbleRemoverPlugin.LogBoth(indent + "  -> ParticleSystem found");
				}
			}
			if (indent.Length < 6)
			{
				for (int j = 0; j < parent.childCount; j++)
				{
					LogAllChildTransforms(parent.GetChild(j), indent + "  ");
				}
			}
		}

		private static void DisableAllVisualComponents(Transform effect, string effectName)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			StaffProtectionBubbleRemoverPlugin.LogBoth("Disabling visual components for: " + effectName);
			Renderer[] componentsInChildren = ((Component)effect).GetComponentsInChildren<Renderer>();
			StaffProtectionBubbleRemoverPlugin.LogBoth($"Found {componentsInChildren.Length} renderers");
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				string[] obj = new string[6]
				{
					"Disabling renderer: ",
					((Object)val).name,
					", Material: ",
					null,
					null,
					null
				};
				Material material = val.material;
				obj[3] = ((material != null) ? ((Object)material).name : null);
				obj[4] = ", Shader: ";
				Material material2 = val.material;
				object obj2;
				if (material2 == null)
				{
					obj2 = null;
				}
				else
				{
					Shader shader = material2.shader;
					obj2 = ((shader != null) ? ((Object)shader).name : null);
				}
				obj[5] = (string)obj2;
				StaffProtectionBubbleRemoverPlugin.LogBoth(string.Concat(obj));
				val.enabled = false;
				if (!((Object)(object)val.material != (Object)null))
				{
					continue;
				}
				try
				{
					Material material3 = val.material;
					if (material3.HasProperty("_Color"))
					{
						Color color = material3.color;
						color.a = 0f;
						material3.color = color;
					}
					if (material3.HasProperty("_Alpha"))
					{
						material3.SetFloat("_Alpha", 0f);
					}
				}
				catch (Exception ex)
				{
					StaffProtectionBubbleRemoverPlugin.LogBoth("Could not modify material: " + ex.Message);
				}
			}
			ParticleSystem[] componentsInChildren2 = ((Component)effect).GetComponentsInChildren<ParticleSystem>();
			StaffProtectionBubbleRemoverPlugin.LogBoth($"Found {componentsInChildren2.Length} particle systems");
			ParticleSystem[] array2 = componentsInChildren2;
			foreach (ParticleSystem obj3 in array2)
			{
				obj3.Stop();
				((Component)obj3).gameObject.SetActive(false);
			}
			((Component)effect).gameObject.SetActive(false);
			StaffProtectionBubbleRemoverPlugin.LogBoth("Disabled GameObject: " + effectName);
		}

		private static void DisableSpecificEffectByName(Transform parent, string effectName, bool shouldDisable)
		{
			if (shouldDisable)
			{
				Transform val = parent.Find(effectName);
				if ((Object)(object)val != (Object)null)
				{
					StaffProtectionBubbleRemoverPlugin.LogBoth("Found and disabling specific effect: " + effectName);
					DisableAllVisualComponents(val, effectName);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player))]
	public static class Player_Patch
	{
		private static float lastCleanupTime = 0f;

		private static readonly float cleanupInterval = 1f;

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void Update_Postfix(Player __instance)
		{
			if (StaffProtectionBubbleRemoverPlugin.ModEnabled.Value && !(Time.time - lastCleanupTime < cleanupInterval))
			{
				lastCleanupTime = Time.time;
				CheckAndDisableSpecificEffect(((Component)__instance).transform, "vfx_StaffShield(Clone)", StaffProtectionBubbleRemoverPlugin.DisableStaffShieldVfx.Value);
				CheckAndDisableSpecificEffect(((Component)__instance).transform, "fx_shield_start(Clone)", StaffProtectionBubbleRemoverPlugin.DisableFxShieldStart.Value);
				Transform val = ((Component)__instance).transform.Find("fx_shield_start(Clone)");
				if ((Object)(object)val != (Object)null)
				{
					CheckAndDisableSpecificEffect(val, "Central Orb", StaffProtectionBubbleRemoverPlugin.DisableCentralOrb.Value);
					CheckAndDisableSpecificEffect(val, "Dropping Orb", StaffProtectionBubbleRemoverPlugin.DisableDroppingOrb.Value);
				}
			}
		}

		private static void CheckAndDisableSpecificEffect(Transform parent, string effectName, bool shouldDisable)
		{
			if (!shouldDisable)
			{
				return;
			}
			Transform val = parent.Find(effectName);
			if (!((Object)(object)val != (Object)null) || !((Component)val).gameObject.activeInHierarchy)
			{
				return;
			}
			StaffProtectionBubbleRemoverPlugin.LogBoth("Player Update: Found active effect " + effectName + ", disabling...");
			Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>();
			foreach (Renderer val2 in componentsInChildren)
			{
				if (val2.enabled)
				{
					val2.enabled = false;
				}
			}
			ParticleSystem[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<ParticleSystem>();
			foreach (ParticleSystem val3 in componentsInChildren2)
			{
				if (val3.isPlaying)
				{
					val3.Stop();
				}
			}
			((Component)val).gameObject.SetActive(false);
		}
	}
}