Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MagicWandMod v1.0.0
plugins\MagicWandMod\MagicWandMod.dll
Decompiled 8 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; using UnityEngine.Networking; [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("MagicWandMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MagicWandMod")] [assembly: AssemblyTitle("MagicWandMod")] [assembly: AssemblyVersion("1.0.0.0")] [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 MagicWandMod { [HarmonyPatch] internal static class StatsManagerInitPatch { private static MethodBase? TargetMethod() { Type type = AccessTools.TypeByName("StatsManager"); if (type == null) { return null; } string[] array = new string[5] { "Awake", "Start", "Initialize", "Init", "Setup" }; foreach (string text in array) { MethodInfo methodInfo = AccessTools.Method(type, text, (Type[])null, (Type[])null); if (methodInfo != null) { return methodInfo; } } return null; } private static void Postfix() { if ((Object)(object)WandItemCreator.WandPrefab == (Object)null) { WandItemCreator.TryCreateAndRegister(); } if (!WandItemCreator.RegisteredViaREPOLib) { InjectIntoStatsManager(); } } private static void InjectIntoStatsManager() { if ((Object)(object)WandItemCreator.WandPrefab == (Object)null) { return; } ItemAttributes component = WandItemCreator.WandPrefab.GetComponent<ItemAttributes>(); if ((Object)(object)component?.item == (Object)null) { return; } Type type = AccessTools.TypeByName("StatsManager"); if (type == null) { return; } object obj = GetStaticPropOrField(type, "instance") ?? GetStaticPropOrField(type, "Instance"); if (obj == null) { return; } string[] array = new string[6] { "itemDictionary", "items", "_items", "itemList", "allItems", "itemsMelee" }; foreach (string text in array) { FieldInfo fieldInfo = AccessTools.Field(type, text); if (fieldInfo == null) { continue; } object value = fieldInfo.GetValue(obj); if (value == null) { continue; } MethodInfo method = value.GetType().GetMethod("Add"); if (method == null) { continue; } try { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 1) { method.Invoke(value, new object[1] { component.item }); } else if (parameters.Length == 2) { method.Invoke(value, new object[2] { "Magic Wand", component.item }); } Plugin.Log.LogInfo((object)("[MagicWand] Injected item into StatsManager." + text + ".")); break; } catch { } } } private static object? GetStaticPropOrField(Type t, string name) { try { PropertyInfo property = t.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { return property.GetValue(null); } } catch { } try { FieldInfo field = t.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(null); } } catch { } return null; } } [HarmonyPatch] internal static class PrefabRefPatch { private static MethodBase? TargetMethod() { Type type = AccessTools.TypeByName("PrefabRef"); if (type == null) { Plugin.Log.LogWarning((object)"[MagicWand] PrefabRef type not found — patch skipped."); return null; } MethodInfo methodInfo = AccessTools.PropertyGetter(type, "Prefab"); if (methodInfo == null) { Plugin.Log.LogWarning((object)"[MagicWand] PrefabRef.get_Prefab not found."); return methodInfo; } Plugin.Log.LogInfo((object)"[MagicWand] PrefabRefPatch ready."); return methodInfo; } private static bool Prefix(object __instance, ref GameObject __result) { try { if (AccessTools.Field(__instance.GetType(), "prefabName")?.GetValue(__instance) is string text && WandItemCreator.CustomPrefabs.TryGetValue(text, out GameObject value)) { Plugin.Log.LogInfo((object)("[MagicWand] PrefabRef intercepted (prefix): '" + text + "' → " + ((Object)value).name)); __result = value; return false; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MagicWand] PrefabRef prefix error: " + ex.Message)); } return true; } private static void Postfix(object __instance, ref GameObject __result) { if ((Object)(object)__result != (Object)null) { return; } try { string text = AccessTools.Field(__instance.GetType(), "prefabName")?.GetValue(__instance) as string; if (text != null && WandItemCreator.CustomPrefabs.TryGetValue(text, out GameObject value)) { Plugin.Log.LogInfo((object)("[MagicWand] PrefabRef fallback (postfix): '" + text + "' → " + ((Object)value).name)); __result = value; } else if (text != null && text.Contains("Magic Wand")) { Plugin.Log.LogWarning((object)("[MagicWand] PrefabRef postfix: '" + text + "' not in CustomPrefabs " + $"(dict size={WandItemCreator.CustomPrefabs.Count}).")); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MagicWand] PrefabRef postfix error: " + ex.Message)); } } } [HarmonyPatch] internal static class MeleeAttackSparkPatch { private static MethodBase? TargetMethod() { string[] array = new string[13] { "MeleeTriggerRPC", "ActivateAttackHurtColliders", "EventMelee", "EventMeleeHit", "MeleeHitRPC", "MeleeSwingRPC", "SwingRPC", "ActivateMelee", "DoMeleeAttack", "MeleeAttack", "ItemMeleeRPC", "AttackRPC", "HitRPC" }; foreach (string text in array) { MethodInfo methodInfo = AccessTools.Method(typeof(ItemMelee), text, (Type[])null, (Type[])null); if (methodInfo != null) { Plugin.Log.LogInfo((object)("[MagicWand] MeleeAttackSparkPatch targeting: " + text)); return methodInfo; } } Plugin.Log.LogWarning((object)"[MagicWand] MeleeAttackSparkPatch: no trigger method found — patch skipped."); return null; } private static void Postfix(ItemMelee __instance) { if ((Object)(object)((Component)__instance).GetComponent<WandHitDetector>() == (Object)null) { return; } ParticleSystem[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem obj in componentsInChildren) { if (obj != null) { obj.Emit(5); } } } } [HarmonyPatch(typeof(ItemMelee), "ActivateHitbox")] internal static class ItemMeleeActivateHitboxPatch { private static bool Prefix(ItemMelee __instance) { if (((Object)((Component)__instance).gameObject).name.StartsWith("Magic Wand")) { return false; } return true; } } [HarmonyPatch] internal static class ItemMeleeSwingHitPatch { [CompilerGenerated] private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable { private int <>1__state; private MethodBase <>2__current; private int <>l__initialThreadId; private string[] <>7__wrap1; private int <>7__wrap2; MethodBase IEnumerator<MethodBase>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <TargetMethods>d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; goto IL_00dc; } <>1__state = -1; <>7__wrap1 = new string[10] { "SwingHit", "SwingHitRPC", "PlayerSwingHit", "EnemySwingHit", "EnemyOrPVPSwingHitRPC", "GroundHit", "MeleeBreak", "MeleeBreakRPC", "MeleeFix", "MeleeFixRPC" }; <>7__wrap2 = 0; goto IL_00ea; IL_00dc: <>7__wrap2++; goto IL_00ea; IL_00ea: if (<>7__wrap2 < <>7__wrap1.Length) { string text = <>7__wrap1[<>7__wrap2]; MethodInfo methodInfo = AccessTools.Method(typeof(ItemMelee), text, (Type[])null, (Type[])null); if (methodInfo != null) { Plugin.Log.LogInfo((object)("[MagicWand] SwingHitPatch: suppressing " + text + ".")); <>2__current = methodInfo; <>1__state = 1; return true; } goto IL_00dc; } <>7__wrap1 = null; 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(); } [DebuggerHidden] IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <TargetMethods>d__0(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<MethodBase>)this).GetEnumerator(); } } [IteratorStateMachine(typeof(<TargetMethods>d__0))] private static IEnumerable<MethodBase> TargetMethods() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <TargetMethods>d__0(-2); } private static bool Prefix(ItemMelee __instance) { if (((Object)((Component)__instance).gameObject).name.StartsWith("Magic Wand")) { return false; } return true; } } [HarmonyPatch(typeof(HurtCollider), "OnEnable")] internal static class HurtColliderOnEnablePatch { private static bool Prefix(HurtCollider __instance) { try { Transform val = ((Component)__instance).transform; while ((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)null) { val = val.parent; } if (val != null && ((Object)((Component)val).gameObject).name.StartsWith("Magic Wand")) { Collider component = ((Component)__instance).GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { component.enabled = false; } return false; } } catch { } return true; } } [HarmonyPatch(typeof(ItemMelee), "Update")] internal static class ItemMeleeUpdateGuard { private static Exception? Finalizer(ItemMelee __instance, Exception __exception) { if (__exception == null) { return null; } if ((Object)(object)__instance != (Object)null && ((Object)((Component)__instance).gameObject).name.StartsWith("Magic Wand")) { return null; } return __exception; } } [HarmonyPatch(typeof(ItemMelee), "FixedUpdate")] internal static class ItemMeleeFixedUpdateGuard { private static Exception? Finalizer(ItemMelee __instance, Exception __exception) { if (__exception == null) { return null; } if ((Object)(object)__instance != (Object)null && ((Object)((Component)__instance).gameObject).name.StartsWith("Magic Wand")) { return null; } return __exception; } } public class PlayerColorEffect : MonoBehaviour { [CompilerGenerated] private sealed class <RunEffect>d__4 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerColorEffect <>4__this; public float duration; private PlayerAvatar <pa>5__2; private int <original>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RunEffect>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <pa>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown int num = <>1__state; PlayerColorEffect playerColorEffect = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <pa>5__2 = ((Component)playerColorEffect).GetComponent<PlayerAvatar>(); if ((Object)(object)<pa>5__2 == (Object)null) { return false; } <original>5__3 = GetColorIndex(<pa>5__2); int colorIndex = PickDifferentColorIndex(<original>5__3, 8); ApplyColorIndex(<pa>5__2, colorIndex); <>2__current = (object)new WaitForSeconds(duration); <>1__state = 1; return true; } case 1: <>1__state = -1; ApplyColorIndex(<pa>5__2, <original>5__3); playerColorEffect._routine = null; 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 Coroutine? _routine; private const int COLOR_PALETTE_SIZE = 8; public static void Apply(PlayerAvatar player, float duration) { (((Component)player).GetComponent<PlayerColorEffect>() ?? ((Component)player).gameObject.AddComponent<PlayerColorEffect>()).StartEffect(duration); } private void StartEffect(float duration) { if (_routine != null) { ((MonoBehaviour)this).StopCoroutine(_routine); } _routine = ((MonoBehaviour)this).StartCoroutine(RunEffect(duration)); } [IteratorStateMachine(typeof(<RunEffect>d__4))] private IEnumerator RunEffect(float duration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RunEffect>d__4(0) { <>4__this = this, duration = duration }; } private static int GetColorIndex(PlayerAvatar pa) { string[] array = new string[6] { "colorIndex", "playerColorIndex", "currentColorIndex", "customColorIndex", "selectedColor", "playerColor" }; foreach (string name in array) { FieldInfo field = GetField(typeof(PlayerAvatar), name); if (field == null) { continue; } try { object value = field.GetValue(pa); if (value is int) { return (int)value; } } catch { } } return 0; } private static int PickDifferentColorIndex(int current, int paletteSize) { int num = Random.Range(0, paletteSize - 1); if (num >= current) { num++; } return Mathf.Clamp(num, 0, paletteSize - 1); } private static void ApplyColorIndex(PlayerAvatar pa, int colorIndex) { bool flag = false; try { flag = PhotonNetwork.IsConnected; } catch { } if (flag) { try { PhotonView val = ((Component)pa).GetComponent<PhotonView>() ?? ((Component)pa).GetComponentInParent<PhotonView>(); if ((Object)(object)val != (Object)null) { val.RPC("SetColorRPC", (RpcTarget)0, new object[1] { colorIndex }); return; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MagicWand] Photon RPC failed: " + ex.Message)); } } MethodInfo method = GetMethod(typeof(PlayerAvatar), "PlayerAvatarSetColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { try { method.Invoke(pa, new object[1] { colorIndex }); return; } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[MagicWand] PlayerAvatarSetColor failed: " + ex2.Message)); } } Plugin.Log.LogWarning((object)"[MagicWand] Could not apply color — no method worked."); } private static FieldInfo? GetField(Type type, string name) { Type type2 = type; while (type2 != null) { FieldInfo field = type2.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } type2 = type2.BaseType; } return null; } private static MethodInfo? GetMethod(Type type, string name, BindingFlags flags) { Type type2 = type; while (type2 != null) { MethodInfo method = type2.GetMethod(name, flags); if (method != null) { return method; } type2 = type2.BaseType; } return null; } } [BepInPlugin("com.smokebellew.magicwandmod", "MagicWandMod", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <RegistrationLoop>d__13 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private int <i>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RegistrationLoop>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: <>1__state = -1; <i>5__2++; break; } if (<i>5__2 < 30) { if (WandItemCreator.TryCreateAndRegister()) { return false; } <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } Log.LogWarning((object)"[MagicWand] Could not register Magic Wand after 30 attempts."); 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(); } } public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } public static string PluginDir { get; private set; } private void Awake() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; PluginDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); WandAssets.LoadFromDisk(PluginDir); ((MonoBehaviour)this).StartCoroutine(WandAssets.LoadSoundsFromDisk(PluginDir)); Harmony val = new Harmony("com.smokebellew.magicwandmod"); Type[] types = typeof(Plugin).Assembly.GetTypes(); foreach (Type type in types) { try { val.CreateClassProcessor(type).Patch(); } catch (Exception ex) { Log.LogWarning((object)("[MagicWand] Patch skipped " + type.Name + ": " + ex.Message)); } } ((MonoBehaviour)this).StartCoroutine(RegistrationLoop()); Log.LogInfo((object)"MagicWandMod loaded."); } [IteratorStateMachine(typeof(<RegistrationLoop>d__13))] private IEnumerator RegistrationLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RegistrationLoop>d__13(0); } } internal static class WandAssets { [CompilerGenerated] private sealed class <LoadSoundsFromDisk>d__24 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string pluginDir; private List<AudioClip> <loaded>5__2; private string[] <>7__wrap2; private int <>7__wrap3; private string <name>5__5; private UnityWebRequest <req>5__6; object? IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadSoundsFromDisk>d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <loaded>5__2 = null; <>7__wrap2 = null; <name>5__5 = null; <req>5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Invalid comparison between Unknown and I4 try { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; string[] array = new string[3] { "valuable star wand sparkle01.ogg", "valuable star wand sparkle02.ogg", "valuable star wand sparkle03.ogg" }; <loaded>5__2 = new List<AudioClip>(); <>7__wrap2 = array; <>7__wrap3 = 0; break; } case 1: <>1__state = -3; if ((int)<req>5__6.result == 1) { AudioClip content = DownloadHandlerAudioClip.GetContent(<req>5__6); ((Object)content).name = Path.GetFileNameWithoutExtension(<name>5__5); <loaded>5__2.Add(content); } else { Plugin.Log.LogWarning((object)("[MagicWand] Could not load " + <name>5__5 + ": " + <req>5__6.error)); } <>m__Finally1(); <req>5__6 = null; <name>5__5 = null; <>7__wrap3++; break; } if (<>7__wrap3 < <>7__wrap2.Length) { <name>5__5 = <>7__wrap2[<>7__wrap3]; string text = "file:///" + Path.Combine(pluginDir, <name>5__5).Replace('\\', '/'); <req>5__6 = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)14); <>1__state = -3; <>2__current = <req>5__6.SendWebRequest(); <>1__state = 1; return true; } <>7__wrap2 = null; if (<loaded>5__2.Count > 0) { Sounds = <loaded>5__2.ToArray(); Plugin.Log.LogInfo((object)$"[MagicWand] Loaded {<loaded>5__2.Count} sounds."); } return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<req>5__6 != null) { ((IDisposable)<req>5__6).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const int TEX_OFF = 0; private const int TEX_LEN = 38109; private const int VRT_OFF = 38112; private const int VRT_CNT = 306; private const int VRT_STRIDE = 48; private const int IDX_OFF = 52800; private const int IDX_CNT = 528; public static bool MeshReady { get; private set; } public static Mesh? WandMesh { get; private set; } public static Material? WandMaterial { get; private set; } public static AudioClip[]? Sounds { get; private set; } public static void LoadFromDisk(string pluginDir) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown string text = Path.Combine(pluginDir, "WandPrefab.glb"); if (!File.Exists(text)) { Plugin.Log.LogWarning((object)("[MagicWand] WandPrefab.glb not found at " + text + ".")); return; } if (!TryParseGlb(File.ReadAllBytes(text), out Mesh mesh, out Texture2D tex)) { Plugin.Log.LogError((object)"[MagicWand] Failed to parse WandPrefab.glb."); return; } Material val = new Material(Shader.Find("Unlit/Texture") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Standard")) { name = "Magic Wand" }; val.mainTexture = (Texture)(object)tex; try { val.SetTexture("_BaseMap", (Texture)(object)tex); } catch { } try { val.SetInt("_Cull", 0); } catch { } WandMesh = mesh; WandMaterial = val; MeshReady = true; Plugin.Log.LogInfo((object)$"[MagicWand] Wand mesh loaded ({mesh.vertexCount} verts)."); } [IteratorStateMachine(typeof(<LoadSoundsFromDisk>d__24))] public static IEnumerator LoadSoundsFromDisk(string pluginDir) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadSoundsFromDisk>d__24(0) { pluginDir = pluginDir }; } public static void TryCacheSounds() { if (Sounds != null && Sounds.Length != 0) { return; } List<AudioClip> list = new List<AudioClip>(); AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>(); foreach (AudioClip val in array) { string text = ((Object)val).name.ToLower(); if (text.Contains("wand") && text.Contains("sparkle")) { list.Add(val); } } if (list.Count > 0) { Sounds = list.ToArray(); } } private static bool TryParseGlb(byte[] d, out Mesh mesh, out Texture2D tex) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown mesh = null; tex = null; try { if (d.Length < 28 || BitConverter.ToUInt32(d, 0) != 1179937895) { Plugin.Log.LogError((object)"[MagicWand] Not a valid GLB."); return false; } int num = (int)BitConverter.ToUInt32(d, 12); int num2 = 28 + num; tex = new Texture2D(2, 2, (TextureFormat)4, false); byte[] array = new byte[38109]; Buffer.BlockCopy(d, num2, array, 0, 38109); ImageConversion.LoadImage(tex, array); int num3 = num2 + 38112; Vector3[] array2 = (Vector3[])(object)new Vector3[306]; Vector2[] array3 = (Vector2[])(object)new Vector2[306]; for (int i = 0; i < 306; i++) { int num4 = num3 + i * 48; float num5 = BitConverter.ToSingle(d, num4); float num6 = BitConverter.ToSingle(d, num4 + 4); float num7 = BitConverter.ToSingle(d, num4 + 8); array2[i] = new Vector3(0f - num5, num6, num7); float num8 = BitConverter.ToSingle(d, num4 + 40); float num9 = BitConverter.ToSingle(d, num4 + 44); array3[i] = new Vector2(num8, 1f - num9); } int num10 = num2 + 52800; int[] array4 = new int[528]; for (int j = 0; j < 528; j += 3) { array4[j] = BitConverter.ToUInt16(d, num10 + j * 2); array4[j + 1] = BitConverter.ToUInt16(d, num10 + (j + 2) * 2); array4[j + 2] = BitConverter.ToUInt16(d, num10 + (j + 1) * 2); } mesh = new Mesh { name = "Magic Wand Mesh" }; mesh.vertices = array2; mesh.uv = array3; mesh.triangles = array4; mesh.RecalculateNormals(); mesh.RecalculateBounds(); return true; } catch (Exception ex) { Plugin.Log.LogError((object)("[MagicWand] GLB parse error: " + ex.Message)); return false; } } } public class WandHitDetector : MonoBehaviour { private ItemMelee? _melee; private AudioSource? _audio; private WandTipMarker? _tip; private ParticleSystem? _sparklePs; private HurtCollider[] _hurtColliders = Array.Empty<HurtCollider>(); private Collider[] _hurtColliders_cols = Array.Empty<Collider>(); private ParticleSystem[] _foreignPs = Array.Empty<ParticleSystem>(); private Renderer[] _foreignRenderers = Array.Empty<Renderer>(); private SphereCollider? _hitSphere; private Vector3 _lastPos; private float _soundCooldown; private const float MOVE_THRESHOLD = 0.004f; private const float SOUND_MIN = 0.25f; private const float SOUND_RAND = 0.3f; private float _angularVelMag; private Rigidbody? _rb; private const float SWING_ANG_THRESHOLD = 2.5f; private readonly HashSet<int> _recentlyHit = new HashSet<int>(); private void Start() { //IL_00a9: 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) _melee = ((Component)this).GetComponent<ItemMelee>(); _audio = ((Component)this).GetComponent<AudioSource>(); _rb = ((Component)this).GetComponent<Rigidbody>(); _tip = ((Component)this).GetComponentInChildren<WandTipMarker>(true); if ((Object)(object)_tip != (Object)null) { _sparklePs = ((Component)_tip).GetComponent<ParticleSystem>(); } if ((Object)(object)_tip != (Object)null) { _hitSphere = ((Component)_tip).gameObject.AddComponent<SphereCollider>(); ((Collider)_hitSphere).isTrigger = true; _hitSphere.radius = 0.12f; ((Collider)_hitSphere).enabled = false; } CacheEffectsToSuppress(); _lastPos = ((Component)this).transform.position; SuppressAllBatEffects(); } private void CacheEffectsToSuppress() { _hurtColliders = ((Component)this).GetComponentsInChildren<HurtCollider>(true); _hurtColliders_cols = (Collider[])(object)new Collider[_hurtColliders.Length]; for (int i = 0; i < _hurtColliders.Length; i++) { _hurtColliders_cols[i] = ((Component)_hurtColliders[i]).GetComponent<Collider>(); } ParticleSystem[] componentsInChildren = ((Component)this).GetComponentsInChildren<ParticleSystem>(true); List<ParticleSystem> list = new List<ParticleSystem>(); ParticleSystem[] array = componentsInChildren; foreach (ParticleSystem val in array) { if (!((Object)(object)_tip != (Object)null) || !((Component)val).transform.IsChildOf(((Component)_tip).transform)) { list.Add(val); } } _foreignPs = list.ToArray(); Renderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Renderer>(true); List<Renderer> list2 = new List<Renderer>(); Renderer[] array2 = componentsInChildren2; foreach (Renderer val2 in array2) { if (!(((Object)((Component)val2).gameObject).name == "MagicWandMesh") && (!((Object)(object)_tip != (Object)null) || !((Component)val2).transform.IsChildOf(((Component)_tip).transform))) { list2.Add(val2); } } _foreignRenderers = list2.ToArray(); } private void Update() { UpdateSwingDetection(); UpdateSparkles(); UpdateHitSphere(); } private void LateUpdate() { SuppressAllBatEffects(); } private void SuppressAllBatEffects() { for (int i = 0; i < _hurtColliders.Length; i++) { HurtCollider val = _hurtColliders[i]; if (!((Object)(object)val == (Object)null)) { if (((Behaviour)val).enabled) { ((Behaviour)val).enabled = false; } Collider val2 = _hurtColliders_cols[i]; if ((Object)(object)val2 != (Object)null && val2.enabled) { val2.enabled = false; } } } ParticleSystem[] foreignPs = _foreignPs; foreach (ParticleSystem val3 in foreignPs) { if (!((Object)(object)val3 == (Object)null) && (val3.isEmitting || val3.isPlaying)) { val3.Stop(true, (ParticleSystemStopBehavior)0); } } Renderer[] foreignRenderers = _foreignRenderers; foreach (Renderer val4 in foreignRenderers) { if ((Object)(object)val4 != (Object)null && val4.enabled) { val4.enabled = false; } } } private void UpdateSwingDetection() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_rb != (Object)null) { Vector3 angularVelocity = _rb.angularVelocity; _angularVelMag = ((Vector3)(ref angularVelocity)).magnitude; } else { float num = Vector3.Distance(((Component)this).transform.position, _lastPos); _angularVelMag = num / Time.deltaTime; } } private void UpdateHitSphere() { if (!((Object)(object)_hitSphere == (Object)null)) { bool isMelee = GetIsMelee(); ((Collider)_hitSphere).enabled = isMelee; if (!isMelee) { _recentlyHit.Clear(); } } } private void UpdateSparkles() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) float num = Vector3.Distance(((Component)this).transform.position, _lastPos); _lastPos = ((Component)this).transform.position; _soundCooldown -= Time.deltaTime; if (num < 0.004f) { return; } if ((Object)(object)_sparklePs != (Object)null) { _sparklePs.Emit(1); } if (!(_soundCooldown <= 0f)) { return; } WandAssets.TryCacheSounds(); AudioClip[] sounds = WandAssets.Sounds; if (sounds != null && sounds.Length != 0) { AudioClip val = sounds[Random.Range(0, sounds.Length)]; if ((Object)(object)val != (Object)null && (Object)(object)_audio != (Object)null) { _audio.PlayOneShot(val, 0.15f); } } _soundCooldown = 0.25f + Random.Range(0f, 0.3f); } private void OnTriggerEnter(Collider other) { if (!GetIsMelee()) { return; } PlayerAvatar componentInParent = ((Component)other).GetComponentInParent<PlayerAvatar>(); if ((Object)(object)componentInParent == (Object)null) { return; } int instanceID = ((Object)componentInParent).GetInstanceID(); if (!_recentlyHit.Contains(instanceID)) { _recentlyHit.Add(instanceID); if (!IsOwner(componentInParent)) { Plugin.Log.LogInfo((object)("[MagicWand] Hit player " + ((Object)componentInParent).name + " — applying color effect.")); PlayerColorEffect.Apply(componentInParent, 10f); } } } private bool GetIsMelee() { if ((Object)(object)_melee == (Object)null) { return false; } try { FieldInfo field = typeof(ItemMelee).GetField("isMelee", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return (bool)field.GetValue(_melee); } } catch { } return _angularVelMag > 2.5f; } private bool IsOwner(PlayerAvatar candidate) { try { PhotonView val = ((Component)this).GetComponent<PhotonView>() ?? ((Component)this).GetComponentInParent<PhotonView>(); if ((Object)(object)val != (Object)null && val.IsMine && (Object)(object)FindLocalPlayerAvatar() == (Object)(object)candidate) { return true; } } catch { } return false; } private static PlayerAvatar? FindLocalPlayerAvatar() { try { PropertyInfo property = typeof(PlayerAvatar).GetProperty("local", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { object? value = property.GetValue(null); return (PlayerAvatar?)((value is PlayerAvatar) ? value : null); } FieldInfo field = typeof(PlayerAvatar).GetField("local", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object? value2 = field.GetValue(null); return (PlayerAvatar?)((value2 is PlayerAvatar) ? value2 : null); } } catch { } return null; } } internal static class WandItemCreator { public static readonly Dictionary<string, GameObject> CustomPrefabs = new Dictionary<string, GameObject>(); private static bool _registered; private static readonly string[] BaseWeaponHints = new string[9] { "sword", "stun baton", "baton", "inflatable hammer", "hammer", "frying pan", "frying", "baseball bat", "bat" }; public static GameObject? WandPrefab { get; private set; } public static bool RegisteredViaREPOLib { get; private set; } public static bool TryCreateAndRegister() { if (_registered) { return true; } GameObject val = FindMeleeWeaponPrefab(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[MagicWand] No ItemMelee prefab found yet — will retry later."); return false; } WandPrefab = BuildWandPrefab(val); Register(WandPrefab); _registered = true; Plugin.Log.LogInfo((object)"[MagicWand] Magic Wand registered successfully."); return true; } private static GameObject? FindMeleeWeaponPrefab() { ItemMelee[] array = Resources.FindObjectsOfTypeAll<ItemMelee>(); string[] baseWeaponHints; if (array.Length != 0) { baseWeaponHints = BaseWeaponHints; foreach (string value in baseWeaponHints) { ItemMelee[] array2 = array; foreach (ItemMelee val in array2) { if (((Object)((Component)val).gameObject).name.ToLower().Contains(value)) { return ((Component)val).gameObject; } } } return ((Component)array[0]).gameObject; } GameObject val2 = FindMeleeViaStatsManager(); if ((Object)(object)val2 != (Object)null) { return val2; } ItemAttributes[] array3 = Resources.FindObjectsOfTypeAll<ItemAttributes>(); baseWeaponHints = BaseWeaponHints; ItemAttributes[] array4; foreach (string value2 in baseWeaponHints) { array4 = array3; foreach (ItemAttributes val3 in array4) { if (!((Object)(object)((Component)val3).GetComponent<ItemMelee>() == (Object)null) && ((Object)((Component)val3).gameObject).name.ToLower().Contains(value2)) { return ((Component)val3).gameObject; } } } array4 = array3; foreach (ItemAttributes val4 in array4) { if ((Object)(object)((Component)val4).GetComponent<ItemMelee>() != (Object)null) { return ((Component)val4).gameObject; } } return null; } private static GameObject? FindMeleeViaStatsManager() { try { Type type = AccessTools.TypeByName("StatsManager"); if (type == null) { return null; } object obj = GetStaticPropOrField(type, "instance") ?? GetStaticPropOrField(type, "Instance"); if (obj == null) { return null; } FieldInfo fieldInfo = AccessTools.Field(type, "itemDictionary"); if (fieldInfo == null) { return null; } object value = fieldInfo.GetValue(obj); if (value == null) { return null; } return TryFindMeleeInCollection(value); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MagicWand] StatsManager search error: " + ex.Message)); } return null; } private static GameObject? TryFindMeleeInCollection(object collection) { PropertyInfo property = collection.GetType().GetProperty("Values"); if (!(((property != null) ? property.GetValue(collection) : collection) is IEnumerable enumerable)) { return null; } List<GameObject> list = new List<GameObject>(); foreach (object item in enumerable) { if (item != null) { GameObject val = ResolveItemPrefab(item); if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<ItemMelee>() != (Object)null) { list.Add(val); } } } string[] baseWeaponHints = BaseWeaponHints; foreach (string value in baseWeaponHints) { foreach (GameObject item2 in list) { if (((Object)item2).name.ToLower().Contains(value)) { return item2; } } } if (list.Count > 0) { return list[0]; } return null; } private static GameObject? ResolveItemPrefab(object item) { GameObject val = (GameObject)((item is GameObject) ? item : null); if (val != null) { return val; } Component val2 = (Component)((item is Component) ? item : null); if (val2 != null) { return val2.gameObject; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; Type type = item.GetType(); while (type != null && type != typeof(object)) { FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo fieldInfo in fields) { try { if (fieldInfo.FieldType == typeof(GameObject)) { object? value = fieldInfo.GetValue(item); GameObject val3 = (GameObject)((value is GameObject) ? value : null); if (val3 != null) { return val3; } } else { if (fieldInfo.FieldType.IsPrimitive || fieldInfo.FieldType.IsEnum || !(fieldInfo.FieldType != typeof(string)) || !fieldInfo.FieldType.IsClass) { continue; } object value2 = fieldInfo.GetValue(item); if (value2 == null) { continue; } FieldInfo[] fields2 = fieldInfo.FieldType.GetFields(bindingAttr); foreach (FieldInfo fieldInfo2 in fields2) { if (fieldInfo2.FieldType == typeof(GameObject)) { object? value3 = fieldInfo2.GetValue(value2); GameObject val4 = (GameObject)((value3 is GameObject) ? value3 : null); if (val4 != null) { return val4; } } } PropertyInfo[] properties = fieldInfo.FieldType.GetProperties(bindingAttr); foreach (PropertyInfo propertyInfo in properties) { if (!(propertyInfo.PropertyType == typeof(GameObject))) { continue; } try { object? value4 = propertyInfo.GetValue(value2); GameObject val5 = (GameObject)((value4 is GameObject) ? value4 : null); if (val5 != null) { return val5; } } catch { } } continue; } } catch { } } type = type.BaseType; } return null; } private static GameObject BuildWandPrefab(GameObject baseGO) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown GameObject val = Object.Instantiate<GameObject>(baseGO); ((Object)val).name = "Magic Wand"; GameObject val2 = new GameObject("MagicWandPrefabHolder"); Object.DontDestroyOnLoad((Object)(object)val2); val2.SetActive(false); val.transform.SetParent(val2.transform, false); Item val3 = CreateItemScriptableObject("Magic Wand", val, baseGO); ItemAttributes component = val.GetComponent<ItemAttributes>(); if ((Object)(object)component != (Object)null && (Object)(object)val3 != (Object)null) { component.item = val3; FieldInfo field = GetField(((object)val3).GetType(), "itemName"); if (string.IsNullOrEmpty(field?.GetValue(val3) as string)) { field?.SetValue(val3, "Magic Wand"); } } ItemMelee component2 = val.GetComponent<ItemMelee>(); if ((Object)(object)component2 != (Object)null) { ZeroEnemyDamage(component2); } RemoveSpecialEffects(val); WandVisuals.Apply(val); val.AddComponent<WandHitDetector>(); CustomPrefabs[((Object)val).name] = val; Plugin.Log.LogInfo((object)("[MagicWand] Prefab built from base '" + ((Object)baseGO).name + "'.")); return val; } private static Item? CreateItemScriptableObject(string displayName, GameObject wandPrefab, GameObject baseGO) { try { Item val = baseGO.GetComponent<ItemAttributes>()?.item; Item val2; if ((Object)(object)val != (Object)null) { val2 = Object.Instantiate<Item>(val); ((Object)val2).name = displayName; } else { val2 = ScriptableObject.CreateInstance<Item>(); } SetFieldFuzzy(val2, displayName, "itemName", "_itemName", "displayName"); UpdatePrefabRef(val2, wandPrefab); return val2; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MagicWand] Could not create Item SO: " + ex.Message)); return null; } } private static void UpdatePrefabRef(Item item, GameObject wandPrefab) { FieldInfo field = GetField(((object)item).GetType(), "prefab"); if (field == null) { return; } object value = field.GetValue(item); if (value == null) { return; } string name = ((Object)wandPrefab).name; FieldInfo[] fields = value.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.FieldType != typeof(string)) && (fieldInfo.Name == "prefabName" || fieldInfo.Name == "resourcePath")) { fieldInfo.SetValue(value, name); } } } private static void ZeroEnemyDamage(ItemMelee melee) { string[] array = new string[4] { "enemyDamage", "_damage", "damage", "meleeDamage" }; foreach (string name in array) { FieldInfo field = GetField(((object)melee).GetType(), name); if (field == null) { continue; } try { if (field.FieldType == typeof(int)) { field.SetValue(melee, 0); } else if (field.FieldType == typeof(float)) { field.SetValue(melee, 0f); } } catch { } } } private static void RemoveSpecialEffects(GameObject go) { ItemBattery[] componentsInChildren = go.GetComponentsInChildren<ItemBattery>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } HurtCollider[] componentsInChildren2 = go.GetComponentsInChildren<HurtCollider>(true); foreach (HurtCollider obj in componentsInChildren2) { ((Behaviour)obj).enabled = false; Collider component = ((Component)obj).GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { component.enabled = false; } } MonoBehaviour[] componentsInChildren3 = go.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren3) { if ((Object)(object)val == (Object)null) { continue; } string name = ((object)val).GetType().Name; switch (name) { case "ItemMelee": case "ItemAttributes": case "ItemEquippable": case "WandHitDetector": case "WandTipMarker": continue; } if (!name.StartsWith("Phys") && !name.StartsWith("Audio") && !(name == "HurtCollider") && (name.Contains("Stun") || name.Contains("Effect") || name.Contains("Smoke") || name.Contains("Trail") || name.Contains("Debris") || name.Contains("Special") || name.Contains("Hurt"))) { try { ((Behaviour)val).enabled = false; } catch { } } } } private static void Register(GameObject wandGO) { if (!TryRegisterViaREPOLib(wandGO)) { Plugin.Log.LogInfo((object)"[MagicWand] REPOLib unavailable — injecting directly into StatsManager."); TryInjectDirectly(wandGO); } } private static bool TryRegisterViaREPOLib(GameObject wandGO) { try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "REPOLib"); if (assembly == null) { return false; } Type type = assembly.GetType("REPOLib.Modules.Items") ?? assembly.GetType("REPOLib.API.Items"); if (type == null) { return false; } MethodInfo method = type.GetMethod("RegisterItem", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemAttributes) }, null); if (method == null) { return false; } ItemAttributes component = wandGO.GetComponent<ItemAttributes>(); if ((Object)(object)component == (Object)null) { return false; } method.Invoke(null, new object[1] { component }); Plugin.Log.LogInfo((object)"[MagicWand] Registered via REPOLib."); RegisteredViaREPOLib = true; return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MagicWand] REPOLib registration failed: " + ex.Message)); return false; } } private static void TryInjectDirectly(GameObject wandGO) { try { Type type = typeof(ItemAttributes).Assembly.GetType("StatsManager"); if (type == null) { Plugin.Log.LogWarning((object)"[MagicWand] StatsManager type not found."); return; } object obj = GetStaticPropOrField(type, "instance") ?? GetStaticPropOrField(type, "Instance"); if (obj == null) { Plugin.Log.LogWarning((object)"[MagicWand] StatsManager instance not available yet."); return; } ItemAttributes component = wandGO.GetComponent<ItemAttributes>(); if ((Object)(object)component?.item == (Object)null) { return; } string[] array = new string[5] { "itemDictionary", "items", "_items", "itemList", "allItems" }; foreach (string text in array) { FieldInfo field = GetField(type, text); if (field == null) { continue; } object value = field.GetValue(obj); if (value == null) { continue; } MethodInfo method = value.GetType().GetMethod("Add"); if (!(method == null)) { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 1) { method.Invoke(value, new object[1] { component.item }); Plugin.Log.LogInfo((object)("[MagicWand] Injected into StatsManager." + text + ".")); return; } if (parameters.Length == 2) { method.Invoke(value, new object[2] { "Magic Wand", component.item }); Plugin.Log.LogInfo((object)("[MagicWand] Injected into StatsManager." + text + " (keyed).")); return; } } } Plugin.Log.LogWarning((object)"[MagicWand] Could not find item collection in StatsManager."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MagicWand] Direct injection failed: " + ex.Message)); } } private static void SetFieldFuzzy(object target, object value, params string[] candidates) { foreach (string name in candidates) { FieldInfo field = GetField(target.GetType(), name); if (!(field == null)) { try { field.SetValue(target, value); break; } catch { } } } } private static FieldInfo? GetField(Type type, string name) { Type type2 = type; while (type2 != null) { FieldInfo field = type2.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } type2 = type2.BaseType; } return null; } private static object? GetStaticPropOrField(Type type, string name) { PropertyInfo property = type.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { try { return property.GetValue(null); } catch { } } FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { try { return field.GetValue(null); } catch { } } return null; } } internal static class EnumerableHelper { public static T? FirstOrDefault<T>(this T[] arr, Func<T, bool> pred) where T : class { foreach (T val in arr) { if (pred(val)) { return val; } } return null; } } internal static class WandVisuals { private static readonly Vector3 MeshRelPos = new Vector3(0f, -0.251f, 0f); private static readonly Quaternion MeshRelRot = Quaternion.identity; private static readonly Vector3 MeshScale = new Vector3(0.272872f, 0.272872f, 0.272872f); private static readonly Vector3 TipRelPos = new Vector3(0f, 0.538f, 0f); private static readonly Quaternion TipRelRot = Quaternion.identity; private static readonly Vector3 TipScale = new Vector3(0.75f, 0.75f, 0.75f); public static void Apply(GameObject wandGO) { //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Expected O, but got Unknown MeshRenderer[] componentsInChildren = wandGO.GetComponentsInChildren<MeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Renderer)componentsInChildren[i]).enabled = false; } SkinnedMeshRenderer[] componentsInChildren2 = wandGO.GetComponentsInChildren<SkinnedMeshRenderer>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Renderer)componentsInChildren2[i]).enabled = false; } TrailRenderer[] componentsInChildren3 = wandGO.GetComponentsInChildren<TrailRenderer>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { ((Renderer)componentsInChildren3[i]).enabled = false; } LineRenderer[] componentsInChildren4 = wandGO.GetComponentsInChildren<LineRenderer>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { ((Renderer)componentsInChildren4[i]).enabled = false; } ParticleSystem[] componentsInChildren5 = wandGO.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val in componentsInChildren5) { val.Stop(true, (ParticleSystemStopBehavior)0); if ((Object)(object)((Component)val).gameObject != (Object)(object)wandGO) { ((Component)val).gameObject.SetActive(false); } } Transform[] componentsInChildren6 = wandGO.GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren6) { if (!((Object)(object)val2 == (Object)(object)wandGO.transform)) { string text = ((Object)((Component)val2).gameObject).name.ToLower(); if (text.Contains("effect") || text.Contains("smoke") || text.Contains("vfx") || text.Contains("debris") || text.Contains("trail") || text.Contains("spark") || text.Contains("glow") || text.Contains("hit") || text.Contains("impact") || text.Contains("particle")) { ((Component)val2).gameObject.SetActive(false); } } } if (!WandAssets.MeshReady) { Plugin.Log.LogWarning((object)"[MagicWand] Wand mesh not loaded — using original weapon model."); return; } GameObject val3 = new GameObject("MagicWandMesh"); val3.transform.SetParent(wandGO.transform, false); val3.transform.localPosition = MeshRelPos; val3.transform.localRotation = MeshRelRot; Vector3 lossyScale = wandGO.transform.lossyScale; Vector3 meshScale = MeshScale; val3.transform.localScale = new Vector3((lossyScale.x > 0f) ? (meshScale.x / lossyScale.x) : meshScale.x, (lossyScale.y > 0f) ? (meshScale.y / lossyScale.y) : meshScale.y, (lossyScale.z > 0f) ? (meshScale.z / lossyScale.z) : meshScale.z); val3.AddComponent<MeshFilter>().sharedMesh = WandAssets.WandMesh; ((Renderer)val3.AddComponent<MeshRenderer>()).sharedMaterial = WandAssets.WandMaterial; GameObject val4 = new GameObject("MagicWandTip"); val4.transform.SetParent(wandGO.transform, false); val4.transform.localPosition = TipRelPos; val4.transform.localRotation = TipRelRot; val4.transform.localScale = TipScale; val4.AddComponent<WandTipMarker>(); BuildProceduralSparkles(val4); AudioSource obj = wandGO.GetComponent<AudioSource>() ?? wandGO.AddComponent<AudioSource>(); obj.spatialBlend = 1f; obj.rolloffMode = (AudioRolloffMode)1; obj.maxDistance = 10f; } private static void BuildProceduralSparkles(GameObject parent) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) ParticleSystem obj = parent.AddComponent<ParticleSystem>(); MainModule main = obj.main; ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).playOnAwake = false; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.4f, 1.2f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.15f, 0.5f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.02f, 0.07f); ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(1f, 0.95f, 0.3f), new Color(0.9f, 0.5f, 1f)); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.03f); EmissionModule emission = obj.emission; ((EmissionModule)(ref emission)).enabled = false; ShapeModule shape = obj.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = 0.01f; ParticleSystemRenderer component = parent.GetComponent<ParticleSystemRenderer>(); component.renderMode = (ParticleSystemRenderMode)0; ((Renderer)component).material = BuildSparkMaterial(); } private static Material BuildSparkMaterial() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown Texture2D mainTexture = BuildGlowTexture(); Shader val = Shader.Find("Particles/Additive") ?? Shader.Find("Legacy Shaders/Particles/Additive") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Transparent"); if (!((Object)(object)val != (Object)null)) { Material val2 = new Material(Shader.Find("Standard") ?? Shader.Find("Diffuse")); val2.SetInt("_SrcBlend", 5); val2.SetInt("_DstBlend", 1); val2.SetInt("_ZWrite", 0); val2.SetFloat("_Mode", 1f); val2.EnableKeyword("_ALPHAPREMULTIPLY_ON"); val2.renderQueue = 3000; val2.mainTexture = (Texture)(object)mainTexture; val2.color = new Color(1f, 0.92f, 0.3f); return val2; } return new Material(val) { mainTexture = (Texture)(object)mainTexture, color = new Color(1f, 0.92f, 0.3f) }; } private static Texture2D BuildGlowTexture() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false); float num = 15.5f; float num2 = 15.5f; float num3 = num; Color[] array = (Color[])(object)new Color[1024]; for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { float num4 = (float)j - num; float num5 = (float)i - num2; float num6 = Mathf.Clamp01(Mathf.Sqrt(num4 * num4 + num5 * num5) / num3); float num7 = (1f - num6) * (1f - num6); array[i * 32 + j] = new Color(1f, 1f, 1f, num7); } } val.SetPixels(array); val.Apply(); return val; } } public class WandTipMarker : MonoBehaviour { } }