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 LoomConfig v1.0.1
LoomConfig.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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 ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using Unity.VisualScripting; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("BLOKBUSTR")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+2a706361a94fd2b10b69756422cca3448b49fa8c")] [assembly: AssemblyProduct("LoomConfig")] [assembly: AssemblyTitle("LoomConfig")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] 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; } } } namespace LoomConfig { [HarmonyPatch(typeof(EnemyShadowAnim))] public class EnemyShadowAnimPatch { [HarmonyPrefix] [HarmonyPatch("Update")] public static void UpdatePrefix(EnemyShadowAnim __instance) { float value = LoomConfig.configIdleLoopVolume.Value; if (!Mathf.Approximately(value, 0.1f) && !Mathf.Approximately(value, __instance.idleLoop.Volume)) { __instance.idleLoop.Volume = value; } } [HarmonyPrefix] [HarmonyPatch("PlayClapSound")] public static bool PlayClapSoundPrefix(EnemyShadowAnim __instance) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (!LoomConfig.configFixGlobalClapAudio.Value) { LoomConfig.Debug("Played globalClapSound at vanilla position (Vector3.zero)", (MonoBehaviour?)(object)__instance); return true; } __instance.clapSound.Play(((Component)__instance).transform.position, 1f, 1f, 1f, 1f); __instance.globalClapSound.Play(((Component)__instance).transform.position, 1f, 1f, 1f, 1f); LoomConfig.Debug($"Played globalClapSound at fixed position (transform.position: {((Component)__instance).transform.position})", (MonoBehaviour?)(object)__instance); return false; } } [HarmonyPatch(typeof(EnemyShadow))] public static class EnemyShadowPatch { [HarmonyPostfix] [HarmonyPatch("Awake")] public static void AwakePostfix(EnemyShadow __instance) { LoomConfig.Debug("Applying custom properties to new Loom, if any", (MonoBehaviour?)(object)__instance); EnemyShadowUtil enemyShadowUtil = ComponentHolderProtocol.AddComponent<EnemyShadowUtil>((Object)(object)__instance); enemyShadowUtil.enemyShadow = __instance; ((MonoBehaviour)enemyShadowUtil).StartCoroutine(enemyShadowUtil.SetDelayedProperties()); if (SemiFunc.IsNotMasterClient()) { return; } int value = LoomConfig.configMaxHealth.Value; if (value != 500) { EnemyHealth component = ((Component)__instance).GetComponent<EnemyHealth>(); if (Object.op_Implicit((Object)(object)component)) { component.health = value; component.healthCurrent = value; LoomConfig.Debug($"Changed health to {value}", (MonoBehaviour?)(object)__instance); } else { LoomConfig.Error("EnemyHealth component not found!", (MonoBehaviour?)(object)__instance); } } int value2 = LoomConfig.configClapEnemyDamage.Value; if (value2 != 20) { __instance.hurtColliderScript.enemyDamage = value2; LoomConfig.Debug($"Changed clap enemy damage to {value2}", (MonoBehaviour?)(object)__instance); } } [HarmonyPostfix] [HarmonyPatch("StateLeave")] public static void StateLeavePostfix(EnemyShadow __instance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)__instance.currentState == 8) { float value = LoomConfig.configMovementSpeedLeave.Value; if (!Mathf.Approximately(value, 2.5f)) { __instance.enemy.NavMeshAgent.OverrideAgent(value, 30f, 0.1f); } } } [HarmonyPrefix] [HarmonyPatch("BendLogic")] public static void BendLogicPrefix(EnemyShadow __instance) { float value = LoomConfig.configPlayerLookDistance.Value; if (!Mathf.Approximately(value, 7f) && !Mathf.Approximately(value, __instance.distanceFromPlayer)) { __instance.closeEnoughToLook = __instance.distanceFromPlayer < value; } } } [HarmonyPatch(typeof(EnemyShadowScreenVeinEffect))] public class EnemyShadowScreenVeinEffectPatch { [HarmonyPrefix] [HarmonyPatch("Start")] public static void StartPrefix(EnemyShadowScreenVeinEffect __instance) { if (!LoomConfig.configScreenEffectShowHands.Value) { ((Renderer)__instance.handSpriteRenderer).enabled = false; } if (!LoomConfig.configScreenEffectShowVeins.Value) { ((Renderer)__instance.veinSpriteRenderer).enabled = false; } } } public class EnemyShadowUtil : MonoBehaviour { [CompilerGenerated] private sealed class <SetDelayedProperties>d__1 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public EnemyShadowUtil <>4__this; private int <playerDamage>5__1; private float <speed>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SetDelayedProperties>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; break; case 2: <>1__state = -1; break; } if (!Object.op_Implicit((Object)(object)<>4__this.enemyShadow.enemy.NavMeshAgent?.Agent)) { LoomConfig.Debug("Delaying other properties, NavMeshAgent is not fully set up", (MonoBehaviour?)(object)<>4__this.enemyShadow); <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 2; return true; } <playerDamage>5__1 = LoomConfig.configClapPlayerDamage.Value; if (SemiFunc.IsNotMasterClient()) { <playerDamage>5__1 = LoomConfigRoomProperties.GetClapPlayerDamage(); } if (<playerDamage>5__1 != 100) { <>4__this.enemyShadow.hurtColliderScript.playerDamage = <playerDamage>5__1; LoomConfig.Debug($"Changed clap player damage to {<playerDamage>5__1}", (MonoBehaviour?)(object)<>4__this.enemyShadow); } if (SemiFunc.IsNotMasterClient()) { return false; } <speed>5__2 = LoomConfig.configMovementSpeed.Value; if (!Mathf.Approximately(<speed>5__2, 1.2f)) { <>4__this.enemyShadow.enemy.NavMeshAgent.Agent.speed = <speed>5__2; <>4__this.enemyShadow.enemy.NavMeshAgent.DefaultSpeed = <speed>5__2; LoomConfig.Debug($"Changed movement speed to {<speed>5__2}", (MonoBehaviour?)(object)<>4__this.enemyShadow); } 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 EnemyShadow enemyShadow; [IteratorStateMachine(typeof(<SetDelayedProperties>d__1))] public IEnumerator SetDelayedProperties() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SetDelayedProperties>d__1(0) { <>4__this = this }; } } [BepInPlugin("BLOKBUSTR.LoomConfig", "LoomConfig", "1.0.1")] public class LoomConfig : BaseUnityPlugin { public static ConfigEntry<int> configMaxHealth; public static ConfigEntry<int> configClapPlayerDamage; public static ConfigEntry<int> configClapEnemyDamage; public static ConfigEntry<float> configMovementSpeed; public static ConfigEntry<float> configMovementSpeedLeave; public static ConfigEntry<float> configPlayerLookDistance; public static ConfigEntry<bool> configScreenEffectShowHands; public static ConfigEntry<bool> configScreenEffectShowVeins; public static ConfigEntry<float> configIdleLoopVolume; public static ConfigEntry<bool> configFixGlobalClapAudio; private static ConfigEntry<bool> configEnableDebug; internal static LoomConfig Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; RegisterConfig(); Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); Debug("Debug logging is enabled."); } private void RegisterConfig() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Expected O, but got Unknown //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Expected O, but got Unknown configMaxHealth = ((BaseUnityPlugin)this).Config.Bind<int>("Mechanical", "MaxHealth", 500, new ConfigDescription("The maximum health of Loom.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 1000), Array.Empty<object>())); configClapPlayerDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Mechanical", "ClapPlayerDamage", 100, new ConfigDescription("The amount of damage dealt to players by the clap attack. This setting will be synced to all clients in multiplayer.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())); configClapEnemyDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Mechanical", "ClapEnemyDamage", 20, new ConfigDescription("The amount of damage dealt to enemies by the clap attack.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())); configMovementSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Mechanical", "MovementSpeed", 1.2f, new ConfigDescription("The base movement speed of Loom.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 4f), Array.Empty<object>())); configMovementSpeedLeave = ((BaseUnityPlugin)this).Config.Bind<float>("Mechanical", "MovementSpeedLeave", 2.5f, new ConfigDescription("The movement speed of Loom in her Leave state.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 4f), Array.Empty<object>())); configPlayerLookDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "PlayerLookDistance", 7f, new ConfigDescription("The distance at which Loom considers herself close enough to look at the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 15f), Array.Empty<object>())); configScreenEffectShowHands = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ScreenEffectShowHands", true, new ConfigDescription("Whether to show the hand layer in the \"targeted\" screen effect.", (AcceptableValueBase)null, Array.Empty<object>())); configScreenEffectShowVeins = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ScreenEffectShowVeins", true, new ConfigDescription("Whether to show the vein layer in the \"targeted\" screen effect.", (AcceptableValueBase)null, Array.Empty<object>())); configIdleLoopVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "IdleLoopVolume", 0.1f, new ConfigDescription("The volume of the idleLoop sound.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.2f), Array.Empty<object>())); configFixGlobalClapAudio = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "FixGlobalClapAudio", true, new ConfigDescription("Patches a vanilla oversight where the globalClapSound is played at the world origin rather than at Loom's actual location. The local clapSound is unaffected by this bug.", (AcceptableValueBase)null, Array.Empty<object>())); configEnableDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebug", false, new ConfigDescription("Whether to enable debug logging. Keep this disabled for normal gameplay.", (AcceptableValueBase)null, Array.Empty<object>())); } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal static void Debug(string message, MonoBehaviour? instance = null) { if (configEnableDebug.Value) { string text = (Object.op_Implicit((Object)(object)instance) ? $"{((Object)instance).GetInstanceID()}: " : string.Empty); Logger.LogDebug((object)(text + message)); } } internal static void Error(string message, MonoBehaviour? instance = null) { string text = (Object.op_Implicit((Object)(object)instance) ? $"{((Object)instance).GetInstanceID()}: " : string.Empty); Logger.LogDebug((object)(text + message)); } } public static class LoomConfigRoomProperties { internal const string LOOM_CLAP_PLAYER_DAMAGE = "LoomClapPlayerDamage"; public static void SetLoomProperties() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0079: Expected O, but got Unknown if (!SemiFunc.IsNotMasterClient() && SemiFunc.IsMultiplayer()) { int value = LoomConfig.configClapPlayerDamage.Value; if (value == GetClapPlayerDamage()) { LoomConfig.Debug("playerDamage is the same, no need to sync"); return; } LoomConfig.Debug($"Setting Custom Room (Loom) Properties | playerDamage: {value}"); Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"LoomClapPlayerDamage", (object)value); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } public static object? GetLoomProperties(string key) { if (!((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).ContainsKey((object)key)) { return null; } object obj = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties[(object)key]; LoomConfig.Debug($"Getting Custom Room (Loom) Properties | key: {key} | damage: {obj}"); return obj; } public static int GetClapPlayerDamage() { object loomProperties = GetLoomProperties("LoomClapPlayerDamage"); return (loomProperties == null) ? (-1) : ((int)loomProperties); } } [HarmonyPatch(typeof(RunManager))] public class RunManagerHook { [HarmonyPostfix] [HarmonyPatch("ChangeLevel")] public static void ChangeLevelPostfix(bool _levelFailed) { if (!_levelFailed) { LoomConfigRoomProperties.SetLoomProperties(); } } } }