Decompiled source of RepoGodMode v0.2.5

RepoGodMode.dll

Decompiled 2 hours ago
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<bool> Enabled { get; private set; } = null;


		internal static ConfigEntry<KeyboardShortcut> ToggleShortcut { get; private set; } = null;


		internal static ConfigEntry<bool> 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<bool>("General", "Enabled", true, "Turn the mod on or off without uninstalling it.");
			ToggleShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "ToggleShortcut", new KeyboardShortcut((KeyCode)103, Array.Empty<KeyCode>()), "Shortcut used to toggle god mode for the local player.");
			ShowHud = ((BaseUnityPlugin)this).Config.Bind<bool>("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);
		}
	}
}