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 Jester Adrenaline v1.1.0
BepInEx\plugins\JesterAdrenaline\JesterAdrenaline.dll
Decompiled 2 weeks agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Collections; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("JesterAdrenaline")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("JesterAdrenaline")] [assembly: AssemblyTitle("JesterAdrenaline")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [BepInPlugin("wiktor.jesterstamina", "Jester Adrenaline", "1.1.0")] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(JesterAI), "Update")] private static class JesterUpdatePatch { private static void Postfix(JesterAI __instance) { ReportJesterState(__instance); } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] private static class PlayerUpdatePatch { private static void Postfix(PlayerControllerB __instance) { if ((Object)(object)__instance == (Object)(object)StartOfRound.Instance?.localPlayerController) { UpdateNetworking(); UpdatePlayerBoost(__instance); } } } private sealed class ManualLogSourceAdapter { private readonly ManualLogSource source; public ManualLogSourceAdapter(ManualLogSource source) { this.source = source; } public void LogInfo(string message) { source.LogInfo((object)message); } } [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnChaseStateMessage; } private const string ModGuid = "wiktor.jesterstamina"; private const string ModName = "Jester Adrenaline"; private const string ModVersion = "1.1.0"; private const int JesterChasingState = 2; private const string ChaseStateMessageName = "wiktor.jesterstamina.ChaseState"; private const float ChaseSignalTimeout = 0.75f; private const float NetworkSendInterval = 0.15f; private static readonly FieldInfo HasEnteredChaseModeFullyField = typeof(JesterAI).GetField("hasEnteredChaseModeFully", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static ConfigEntry<float> speedMultiplier; private static ConfigEntry<bool> debugLogs; private static ManualLogSourceAdapter logger; private static readonly Harmony Harmony = new Harmony("wiktor.jesterstamina"); private static PlayerControllerB boostedPlayer; private static float originalMovementSpeed; private static float appliedMovementSpeed; private static bool hasAppliedSpeedBoost; private static bool wasJesterChasing; private static float lastJesterChaseTime = -999f; private static bool networkJesterChasing; private static float lastNetworkChaseSignalTime = -999f; private static float nextNetworkSendTime; private static bool lastSentChaseState; private static bool hasSentChaseState; private static bool messageRegistered; private static NetworkManager registeredNetworkManager; private static float nextDebugTime; private void Awake() { logger = new ManualLogSourceAdapter(((BaseUnityPlugin)this).Logger); speedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SpeedMultiplier", 1.15f, "How much faster the local player runs while a Jester is chasing. 1.15 = 15% faster."); debugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogs", false, "Enable extra logs when Jester chase mode starts or ends."); Harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Jester Adrenaline 1.1.0 loaded."); } private static bool IsJesterChasingRecently() { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsListening) { return false; } if (singleton.IsHost || singleton.IsServer) { return Time.time - lastJesterChaseTime <= 0.75f; } if (networkJesterChasing) { return Time.time - lastNetworkChaseSignalTime <= 0.75f; } return false; } private static void UpdatePlayerBoost(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { RemoveBoost(); return; } bool flag = IsJesterChasingRecently(); if (flag) { ApplyBoost(player); } else { RemoveBoost(); } if (debugLogs.Value && flag != wasJesterChasing) { logger.LogInfo(flag ? "Jester chase detected. Stamina and speed boost enabled." : "Jester chase ended. Speed boost removed."); } wasJesterChasing = flag; } private static void ReportJesterState(JesterAI jester) { if ((Object)(object)jester == (Object)null) { return; } NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsListening || (!singleton.IsHost && !singleton.IsServer)) { return; } bool flag = default(bool); int num; if (HasEnteredChaseModeFullyField != null) { object value = HasEnteredChaseModeFullyField.GetValue(jester); if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } } else { num = 0; } bool flag2 = (byte)((uint)num & (flag ? 1u : 0u)) != 0; bool flag3 = ((EnemyAI)jester).currentBehaviourStateIndex >= 2 || flag2; if (flag3) { lastJesterChaseTime = Time.time; } if (debugLogs.Value && Time.time >= nextDebugTime) { nextDebugTime = Time.time + 2f; logger.LogInfo($"Jester patched update; state={((EnemyAI)jester).currentBehaviourStateIndex}, hasEnteredChaseModeFully={flag2}, chasing={flag3}"); } } private static void UpdateNetworking() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsListening || singleton.CustomMessagingManager == null) { ResetNetworking(); return; } if (!messageRegistered || (Object)(object)registeredNetworkManager != (Object)(object)singleton) { NetworkManager obj = registeredNetworkManager; if (obj != null) { CustomMessagingManager customMessagingManager = obj.CustomMessagingManager; if (customMessagingManager != null) { customMessagingManager.UnregisterNamedMessageHandler("wiktor.jesterstamina.ChaseState"); } } CustomMessagingManager customMessagingManager2 = singleton.CustomMessagingManager; object obj2 = <>O.<0>__OnChaseStateMessage; if (obj2 == null) { HandleNamedMessageDelegate val = OnChaseStateMessage; <>O.<0>__OnChaseStateMessage = val; obj2 = (object)val; } customMessagingManager2.RegisterNamedMessageHandler("wiktor.jesterstamina.ChaseState", (HandleNamedMessageDelegate)obj2); registeredNetworkManager = singleton; messageRegistered = true; logger.LogInfo("Registered network chase-state message handler."); } if (singleton.IsHost || singleton.IsServer) { bool flag = Time.time - lastJesterChaseTime <= 0.75f; if (Time.time >= nextNetworkSendTime || !hasSentChaseState || flag != lastSentChaseState) { nextNetworkSendTime = Time.time + 0.15f; lastSentChaseState = flag; hasSentChaseState = true; networkJesterChasing = flag; lastNetworkChaseSignalTime = Time.time; SendChaseStateToClients(singleton, flag); } } } private static void ResetNetworking() { if (messageRegistered && (Object)(object)registeredNetworkManager != (Object)null && registeredNetworkManager.CustomMessagingManager != null) { registeredNetworkManager.CustomMessagingManager.UnregisterNamedMessageHandler("wiktor.jesterstamina.ChaseState"); } messageRegistered = false; registeredNetworkManager = null; networkJesterChasing = false; hasSentChaseState = false; lastSentChaseState = false; lastNetworkChaseSignalTime = -999f; } private static void SendChaseStateToClients(NetworkManager networkManager, bool isChasing) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(1, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref isChasing, default(ForPrimitives)); networkManager.CustomMessagingManager.SendNamedMessageToAll("wiktor.jesterstamina.ChaseState", val, (NetworkDelivery)0); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } private static void OnChaseStateMessage(ulong senderClientId, FastBufferReader reader) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton == (Object)null) && (singleton.IsHost || senderClientId == 0L)) { bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives)); networkJesterChasing = flag; lastNetworkChaseSignalTime = Time.time; if (debugLogs.Value) { logger.LogInfo($"Received host Jester chase state: {flag}"); } } } private static void ApplyBoost(PlayerControllerB player) { player.sprintMeter = 1f; player.isExhausted = false; if (!hasAppliedSpeedBoost || (Object)(object)boostedPlayer != (Object)(object)player) { RemoveBoost(); boostedPlayer = player; originalMovementSpeed = player.movementSpeed; hasAppliedSpeedBoost = true; } float num = Mathf.Max(1f, speedMultiplier.Value); appliedMovementSpeed = originalMovementSpeed * num; player.movementSpeed = appliedMovementSpeed; } private static void RemoveBoost() { if (!hasAppliedSpeedBoost || (Object)(object)boostedPlayer == (Object)null) { hasAppliedSpeedBoost = false; boostedPlayer = null; return; } if (Mathf.Approximately(boostedPlayer.movementSpeed, appliedMovementSpeed)) { boostedPlayer.movementSpeed = originalMovementSpeed; } hasAppliedSpeedBoost = false; boostedPlayer = null; appliedMovementSpeed = 0f; originalMovementSpeed = 0f; } }