using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [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("RepoGodMode")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Toggle god mode in R.E.P.O. with the G key.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RepoGodMode")] [assembly: AssemblyTitle("RepoGodMode")] [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 RepoStarterMod { [BepInPlugin("com.repo.godmode", "RepoGodMode", "0.2.5")] public sealed class Plugin : BaseUnityPlugin { private static readonly FieldInfo PlayerHealthGodModeField = AccessTools.Field(typeof(PlayerHealth), "godMode"); private static readonly FieldInfo PlayerHealthPlayerAvatarField = AccessTools.Field(typeof(PlayerHealth), "playerAvatar"); private static readonly FieldInfo PlayerHealthHealthField = AccessTools.Field(typeof(PlayerHealth), "health"); private static readonly FieldInfo PlayerHealthMaxHealthField = AccessTools.Field(typeof(PlayerHealth), "maxHealth"); private static readonly FieldInfo PlayerAvatarIsLocalField = AccessTools.Field(typeof(PlayerAvatar), "isLocal"); private static int lastToggleFrame = -1; private readonly Harmony harmony = new Harmony("com.repo.godmode"); private GUIStyle? hudStyle; internal static ManualLogSource Log { get; private set; } = null; internal static ConfigEntry Enabled { get; private set; } = null; internal static ConfigEntry ToggleShortcut { get; private set; } = null; internal static ConfigEntry ShowHud { get; private set; } = null; internal static bool GodModeEnabled { get; private set; } private void Awake() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Turn the mod on or off without uninstalling it."); ToggleShortcut = ((BaseUnityPlugin)this).Config.Bind("Controls", "ToggleShortcut", new KeyboardShortcut((KeyCode)103, Array.Empty()), "Shortcut used to toggle god mode for the local player."); ShowHud = ((BaseUnityPlugin)this).Config.Bind("UI", "ShowHud", true, "Show a bottom-right god mode hint and status."); if (!Enabled.Value) { Log.LogInfo((object)"RepoGodMode is disabled in config."); return; } harmony.PatchAll(); Log.LogInfo((object)"RepoGodMode 0.2.5 loaded."); } private void Update() { if (Enabled.Value) { PollToggleInput("Plugin.Update"); if (GodModeEnabled) { ApplyGodModeToLocalPlayer(); } } } internal static void PollToggleInput(string source) { if (!Enabled.Value || Time.frameCount == lastToggleFrame) { return; } string toggleInputSource = GetToggleInputSource(); if (toggleInputSource != null) { lastToggleFrame = Time.frameCount; ToggleGodMode(source + "/" + toggleInputSource); if (GodModeEnabled) { ApplyGodModeToLocalPlayer(); } } } internal static void TickGodMode() { if (Enabled.Value && GodModeEnabled) { ApplyGodModeToLocalPlayer(); } } private static string? GetToggleInputSource() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = ToggleShortcut.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { return "BepInExShortcut"; } if (Input.GetKeyDown((KeyCode)103)) { return "UnityLegacyInput"; } Keyboard current = Keyboard.current; if (current != null && ((ButtonControl)current.gKey).wasPressedThisFrame) { return "UnityInputSystem"; } return null; } private void OnGUI() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (Enabled.Value && ShowHud.Value) { if (hudStyle == null) { hudStyle = CreateHudStyle(); } string text = (IsLocalPlayerCurrentlyGodMode() ? "ON" : "OFF"); string text2 = "G: God Mode " + text; Rect val = default(Rect); ((Rect)(ref val))..ctor((float)Screen.width - 220f - 18f, (float)Screen.height - 34f - 18f, 220f, 34f); GUI.Box(val, GUIContent.none); GUI.Label(val, text2, hudStyle); } } internal static bool IsProtected(PlayerHealth? playerHealth) { if (!Enabled.Value || !GodModeEnabled || (Object)(object)playerHealth == (Object)null) { return false; } PlayerAvatar playerAvatar = GetPlayerAvatar(playerHealth); return IsLocalPlayer(playerAvatar); } internal static bool IsProtected(PlayerAvatar? playerAvatar) { return Enabled.Value && GodModeEnabled && IsLocalPlayerAvatar(playerAvatar); } internal static bool IsLocalPlayerAvatar(PlayerAvatar? playerAvatar) { return IsLocalPlayer(playerAvatar); } private static void ToggleGodMode(string source) { bool flag = GodModeEnabled || IsLocalPlayerCurrentlyGodMode(); SetGodMode(!flag, source); } private static void SetGodMode(bool enabled, string source) { GodModeEnabled = enabled; ApplyGodModeToLocalPlayer(); Log.LogInfo((object)("God mode " + (enabled ? "enabled" : "disabled") + " by " + source + ".")); } private static bool IsLocalPlayerCurrentlyGodMode() { PlayerHealth val = PlayerAvatar.instance?.playerHealth; return (Object)(object)val != (Object)null && GetGodMode(val); } private static void ApplyGodModeToLocalPlayer() { PlayerHealth val = PlayerAvatar.instance?.playerHealth; if ((Object)(object)val == (Object)null) { return; } SetGodModeField(val, GodModeEnabled); if (GodModeEnabled) { val.InvincibleSet(999999f); int intField = GetIntField(PlayerHealthMaxHealthField, val); int intField2 = GetIntField(PlayerHealthHealthField, val); if (intField > 0 && intField2 < intField) { PlayerHealthHealthField.SetValue(val, intField); } } } private static bool GetGodMode(PlayerHealth playerHealth) { object value = PlayerHealthGodModeField.GetValue(playerHealth); return value is bool && (bool)value; } private static void SetGodModeField(PlayerHealth playerHealth, bool enabled) { PlayerHealthGodModeField.SetValue(playerHealth, enabled); } private static PlayerAvatar? GetPlayerAvatar(PlayerHealth playerHealth) { object? value = PlayerHealthPlayerAvatarField.GetValue(playerHealth); return (PlayerAvatar?)((value is PlayerAvatar) ? value : null); } private static bool IsLocalPlayer(PlayerAvatar? playerAvatar) { int result; if ((Object)(object)playerAvatar != (Object)null) { object value = PlayerAvatarIsLocalField.GetValue(playerAvatar); result = ((value is bool && (bool)value) ? 1 : 0); } else { result = 0; } return (byte)result != 0; } private static int GetIntField(FieldInfo field, object instance) { return (field.GetValue(instance) is int num) ? num : 0; } private static GUIStyle CreateHudStyle() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown GUIStyle val = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 18, fontStyle = (FontStyle)1 }; val.normal.textColor = Color.white; return val; } private void OnDestroy() { GodModeEnabled = false; ApplyGodModeToLocalPlayer(); harmony.UnpatchSelf(); } } internal static class PluginInfo { internal const string Guid = "com.repo.godmode"; internal const string Name = "RepoGodMode"; internal const string Version = "0.2.5"; } } namespace RepoStarterMod.Patches { [HarmonyPatch(typeof(PlayerAvatar), "Update")] internal static class PlayerAvatarUpdatePatch { private static void Postfix(PlayerAvatar __instance) { if (Plugin.IsLocalPlayerAvatar(__instance)) { Plugin.PollToggleInput("PlayerAvatar.Update"); Plugin.TickGodMode(); } } } [HarmonyPatch(typeof(PlayerHealth), "Hurt")] internal static class PlayerHealthHurtPatch { private static bool Prefix(PlayerHealth __instance) { return !Plugin.IsProtected(__instance); } } [HarmonyPatch(typeof(PlayerHealth), "HurtOther")] internal static class PlayerHealthHurtOtherPatch { private static bool Prefix(PlayerHealth __instance) { return !Plugin.IsProtected(__instance); } } [HarmonyPatch(typeof(PlayerHealth), "Death")] internal static class PlayerHealthDeathPatch { private static bool Prefix(PlayerHealth __instance) { return !Plugin.IsProtected(__instance); } } [HarmonyPatch(typeof(PlayerAvatar), "PlayerDeath")] internal static class PlayerAvatarPlayerDeathPatch { private static bool Prefix(PlayerAvatar __instance) { return !Plugin.IsProtected(__instance); } } }