using System; 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 Berserk.Patches; using Character_Stats; using HarmonyLib; using Microsoft.CodeAnalysis; using Relay; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("headclef")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+bd5b65836f13a21771e769d6a6efee1d191c28e0")] [assembly: AssemblyProduct("Berserk")] [assembly: AssemblyTitle("Berserk")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 Berserk { [BepInPlugin("headclef.Berserk", "Berserk", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Berserk : BaseUnityPlugin { private const string PluginGuid = "headclef.Berserk"; private const string PluginName = "Berserk"; private const string PluginVersion = "1.1.0"; internal static ConfigEntry ToggleKey; internal static ConfigEntry HealthDrainPerSecond; internal static ConfigEntry StrengthBonus; internal static ConfigEntry LaunchBonus; internal static ConfigEntry CanBeLethal; internal static ConfigEntry ShowIndicator; private static Texture2D? _whiteTex; internal static Berserk Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } public static bool IsActive => BerserkPatch.IsActive; public static int ActiveStrengthBonus => BerserkPatch.ActiveStrengthBonus; public static int ActiveLaunchBonus => BerserkPatch.ActiveLaunchBonus; private static Texture2D WhiteTex { get { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_whiteTex == (Object)null) { _whiteTex = new Texture2D(1, 1); _whiteTex.SetPixel(0, 0, Color.white); _whiteTex.Apply(); } return _whiteTex; } } private void Awake() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_004f: Expected O, but got Unknown Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; BindConfiguration(); if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } private void OnDestroy() { BerserkPatch.ForceDeactivate(); Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void BindConfiguration() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown ToggleKey = ((BaseUnityPlugin)this).Config.Bind("Berserk", "Toggle Key", new KeyboardShortcut((KeyCode)98, Array.Empty()), "Key to toggle the berserk state on and off."); HealthDrainPerSecond = ((BaseUnityPlugin)this).Config.Bind("Berserk", "Health Drain Per Second", 10f, new ConfigDescription("Health drained every second while berserk is active. Can kill you (see Can Be Lethal).", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); StrengthBonus = ((BaseUnityPlugin)this).Config.Bind("Berserk", "Strength Bonus", 5, new ConfigDescription("Temporary Strength levels added while berserk is active (real grab/throw power plus everything that reads your Strength level).", (AcceptableValueBase)(object)new AcceptableValueRange(0, 50), Array.Empty())); LaunchBonus = ((BaseUnityPlugin)this).Config.Bind("Berserk", "Launch Bonus", 5, new ConfigDescription("Temporary Tumble Launch levels added while berserk is active (real launch force plus everything that reads your Launch level).", (AcceptableValueBase)(object)new AcceptableValueRange(0, 50), Array.Empty())); CanBeLethal = ((BaseUnityPlugin)this).Config.Bind("Berserk", "Can Be Lethal", true, "If true, the drain can take you to 0 HP and kill you. If false, the drain stops at 1 HP and never kills you directly."); ShowIndicator = ((BaseUnityPlugin)this).Config.Bind("Berserk", "Show Indicator", true, "Show the on-screen BERSERK indicator while the state is active."); } private static void FillRect(Rect r, Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //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_0017: Unknown result type (might be due to invalid IL or missing references) Color color = GUI.color; GUI.color = c; GUI.DrawTexture(r, (Texture)(object)WhiteTex); GUI.color = color; } private static void DrawBorder(Rect r, float t, Color c) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) FillRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, t), c); FillRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - t, ((Rect)(ref r)).width, t), c); FillRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), c); FillRect(new Rect(((Rect)(ref r)).xMax - t, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), c); } private void OnGUI() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) if (ShowIndicator.Value && BerserkPatch.IsActive) { float num = Mathf.PingPong(Time.unscaledTime * 2.2f, 1f); float num2 = ((float)Screen.width - 220f) / 2f; float num3 = 52f; Rect val = default(Rect); ((Rect)(ref val))..ctor(num2, num3, 220f, 42f); FillRect(val, new Color(0.42f, 0f, 0f, Mathf.Lerp(0.55f, 0.82f, num))); DrawBorder(val, 2f, new Color(1f, 0.22f, 0.12f, Mathf.Lerp(0.55f, 1f, num))); GUIStyle val2 = new GUIStyle { alignment = (TextAnchor)4, fontSize = 21, fontStyle = (FontStyle)1 }; val2.normal.textColor = new Color(0f, 0f, 0f, 0.85f); GUI.Label(new Rect(num2 + 2f, num3 + 2f, 220f, 42f), "BERSERK", val2); val2.normal.textColor = Color.Lerp(new Color(1f, 0.45f, 0.32f), new Color(1f, 0.12f, 0.06f), num); GUI.Label(val, "BERSERK", val2); } } } } namespace Berserk.Patches { [HarmonyPatch] internal static class BerserkPatch { private const string RelaySource = "headclef.Berserk"; private static bool _active; private static float _drainAccum; private static PlayerAvatar? _appliedAvatar; private static string? _overlaySteamId; private static int _appliedStrengthBonus; private static int _appliedLaunchBonus; private static float _appliedGrabDelta; internal static bool IsActive => _active; internal static int ActiveStrengthBonus { get { if (!_active) { return 0; } return _appliedStrengthBonus; } } internal static int ActiveLaunchBonus { get { if (!_active) { return 0; } return _appliedLaunchBonus; } } private static bool TogglePressed() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = Berserk.ToggleKey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } return true; } private static bool CanActivate(out string reason) { if (!Relay.CanDeliver) { reason = "you are a co-op client and the Relay bridge is not delivering — R.E.P.O. simulates Grab Strength and Tumble Launch on the host, so the bonus could not reach you while the health drain still would. Turn Relay's Multiplayer switch on, and make sure the host runs Relay with it on too"; return false; } reason = string.Empty; return true; } [HarmonyPatch(typeof(PlayerController), "Update")] [HarmonyPostfix] private static void PlayerController_Update_Postfix(PlayerController __instance) { try { if ((Object)(object)__instance != (Object)(object)PlayerController.instance) { return; } PlayerAvatar playerAvatarScript = __instance.playerAvatarScript; if (_active && ((Object)(object)playerAvatarScript == (Object)null || playerAvatarScript.deadSet || !SemiFunc.RunIsLevel())) { Deactivate(); return; } if (TogglePressed()) { if (_active) { Deactivate(); } else if ((Object)(object)playerAvatarScript != (Object)null && !playerAvatarScript.deadSet && SemiFunc.RunIsLevel()) { if (CanActivate(out string reason)) { Activate(playerAvatarScript); } else { Berserk.Logger.LogWarning((object)("Berserk stayed off: " + reason + ".")); } } } if (_active && (Object)(object)playerAvatarScript != (Object)null) { DrainTick(playerAvatarScript); } } catch (Exception ex) { Berserk.Logger.LogError((object)("Berserk update exception: " + ex.Message)); Deactivate(); } } private static void DrainTick(PlayerAvatar avatar) { PlayerHealth playerHealth = avatar.playerHealth; if ((Object)(object)playerHealth == (Object)null) { return; } float value = Berserk.HealthDrainPerSecond.Value; if (value <= 0f) { return; } _drainAccum += value * Time.deltaTime; if (_drainAccum < 1f) { return; } int num = (int)_drainAccum; _drainAccum -= num; int num2 = playerHealth.health - num; if (num2 <= 0) { if (Berserk.CanBeLethal.Value) { playerHealth.health = 0; Deactivate(); avatar.PlayerDeath(-1); } else { playerHealth.health = 1; } } else { playerHealth.health = num2; } } private static void Activate(PlayerAvatar avatar) { if (_active || !CanActivate(out string _)) { return; } string text = (((Object)(object)PlayerController.instance != (Object)null) ? PlayerController.instance.playerSteamID : null); if (!string.IsNullOrEmpty(text)) { int value = Berserk.StrengthBonus.Value; int value2 = Berserk.LaunchBonus.Value; Character_Stats.SetTemporaryBonus(text, "Strength", value); Character_Stats.SetTemporaryBonus(text, "Launch", value2); float num = 0.2f * (float)value; if ((Object)(object)avatar.physGrabber != (Object)null) { PhysGrabber physGrabber = avatar.physGrabber; physGrabber.grabStrength += num; } if ((Object)(object)avatar.tumble != (Object)null) { PlayerTumble tumble = avatar.tumble; tumble.tumbleLaunch += value2; } Relay.Report("headclef.Berserk", "playerUpgradeStrength", value); Relay.Report("headclef.Berserk", "playerUpgradeLaunch", value2); _appliedAvatar = avatar; _overlaySteamId = text; _appliedStrengthBonus = value; _appliedLaunchBonus = value2; _appliedGrabDelta = num; _drainAccum = 0f; _active = true; } } private static void Deactivate() { if (!_active) { return; } _active = false; PlayerAvatar appliedAvatar = _appliedAvatar; if ((Object)(object)appliedAvatar != (Object)null) { if ((Object)(object)appliedAvatar.physGrabber != (Object)null) { PhysGrabber physGrabber = appliedAvatar.physGrabber; physGrabber.grabStrength -= _appliedGrabDelta; } if ((Object)(object)appliedAvatar.tumble != (Object)null) { PlayerTumble tumble = appliedAvatar.tumble; tumble.tumbleLaunch -= _appliedLaunchBonus; } } if (!string.IsNullOrEmpty(_overlaySteamId)) { Character_Stats.ClearTemporaryBonus(_overlaySteamId, "Strength"); Character_Stats.ClearTemporaryBonus(_overlaySteamId, "Launch"); } Relay.Clear("headclef.Berserk"); _appliedAvatar = null; _overlaySteamId = null; _appliedStrengthBonus = 0; _appliedLaunchBonus = 0; _appliedGrabDelta = 0f; _drainAccum = 0f; } [HarmonyPatch(typeof(SemiFunc), "OnSceneSwitch")] [HarmonyPrefix] private static void OnSceneSwitch_Prefix() { ForceDeactivate(); } internal static void ForceDeactivate() { try { Deactivate(); } catch { } } } }