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);
}
}
}