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.1.0
LoomConfig.dll
Decompiled 5 days 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: AssemblyCompany("BLOKBUSTR")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+5fda5134a38d55a53990e71e93394783a360bc00")] [assembly: AssemblyProduct("LoomConfig")] [assembly: AssemblyTitle("LoomConfig")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.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))] internal static class EnemyShadowAnimPatch { [HarmonyPrefix] [HarmonyPatch("Update")] internal 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("playTargetedSound")] internal static bool PlayTargetedSoundPrefix(EnemyShadowAnim __instance) { float value = LoomConfig.configTargetedVolume.Value; if (value <= 0f) { return false; } if (!Mathf.Approximately(value, 0.5f) || !Mathf.Approximately(value, __instance.targeted.Volume)) { __instance.targeted.Volume = value; if (value < 0.2f) { __instance.targeted.VolumeRandom = value * 0.5f; } } return true; } [HarmonyPrefix] [HarmonyPatch("PlayUntargetedSound")] internal static bool PlayUntargetedSoundPrefix(EnemyShadowAnim __instance) { float value = LoomConfig.configNotTargetedVolume.Value; if (value <= 0f) { return false; } if (!Mathf.Approximately(value, 0.5f) || !Mathf.Approximately(value, __instance.notTargeted.Volume)) { __instance.notTargeted.Volume = value; if (value < 0.2f) { __instance.notTargeted.VolumeRandom = value * 0.5f; } } return true; } } [HarmonyPatch(typeof(EnemyShadow))] internal static class EnemyShadowPatch { [HarmonyPostfix] [HarmonyPatch("Awake")] internal 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")] internal 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")] internal 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))] internal static class EnemyShadowScreenVeinEffectPatch { [HarmonyPrefix] [HarmonyPatch("Start")] internal 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 = LoomProperties.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.1.0")] 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<float> configTargetedVolume; public static ConfigEntry<float> configNotTargetedVolume; 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_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Expected O, but got Unknown //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Expected O, but got Unknown configMaxHealth = ((BaseUnityPlugin)this).Config.Bind<int>("Logic", "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>("Logic", "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>("Logic", "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>("Logic", "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>("Logic", "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>("Visuals", "PlayerLookDistance", 7f, new ConfigDescription("The maximum distance at which Loom will look at the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 15f), Array.Empty<object>())); configScreenEffectShowHands = ((BaseUnityPlugin)this).Config.Bind<bool>("Visuals", "ScreenEffectShowHands", true, "Whether to show the hand layer in the \"targeted\" screen effect."); configScreenEffectShowVeins = ((BaseUnityPlugin)this).Config.Bind<bool>("Visuals", "ScreenEffectShowVeins", true, "Whether to show the vein layer in the \"targeted\" screen effect."); 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>())); configTargetedVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "TargetedVolume", 0.5f, new ConfigDescription("The volume of the \"targeted\" sound, played when Loom begins to target you.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); configNotTargetedVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "NotTargetedVolume", 0.5f, new ConfigDescription("The volume of the \"notTargeted\" sound, played when Loom loses interest in you.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); configEnableDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebug", false, "Whether to enable debug logging. Keep this disabled for normal gameplay."); } 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 static void Debug(string message, MonoBehaviour? instance = null) { if (configEnableDebug.Value) { Logger.LogDebug((object)(Object.op_Implicit((Object)(object)instance) ? (((object)instance)?.ToString() + ": " + message) : message)); } } internal static void Error(string message, MonoBehaviour? instance = null) { Logger.LogDebug((object)(Object.op_Implicit((Object)(object)instance) ? (((object)instance)?.ToString() + ": " + message) : message)); } } public static class LoomProperties { 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))] internal static class RunManagerHook { [HarmonyPostfix] [HarmonyPatch("ChangeLevel")] public static void ChangeLevelPostfix(RunManager __instance, bool _levelFailed) { if (!_levelFailed && !SemiFunc.IsLevelArena(RunManager.instance.levelCurrent)) { LoomProperties.SetLoomProperties(); } } } }