Decompiled source of Glyph Override v0.1.2

plugins/GlyphOverride.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
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 HarmonyLib;
using MMTools;
using Microsoft.CodeAnalysis;
using MonoMod.Utils;
using Rewired;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("p1xel8ted")]
[assembly: AssemblyConfiguration("Release-Thunderstore")]
[assembly: AssemblyDescription("GlyphOverride")]
[assembly: AssemblyFileVersion("0.1.2.0")]
[assembly: AssemblyInformationalVersion("0.1.2+3604ae8f417635e885b24903f20ffb59f728ab46")]
[assembly: AssemblyProduct("GlyphOverride")]
[assembly: AssemblyTitle("GlyphOverride")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.2.0")]
[module: UnverifiableCode]
[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;
		}
	}
}
internal sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace GlyphOverride
{
	[BepInPlugin("p1xel8ted.cotl.glyphoverride", "Glyph Override", "0.1.2")]
	[BepInDependency("com.bepis.bepinex.configurationmanager", "18.4.1")]
	public class Plugin : BaseUnityPlugin
	{
		private const string PluginGuid = "p1xel8ted.cotl.glyphoverride";

		private const string PluginName = "Glyph Override";

		private const string PluginVer = "0.1.2";

		private const string ControllerSection = "── Controller ──";

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<ControllerPromptType> ForceControllerType { get; private set; }

		internal static ConfigEntry<ControllerPromptType> ForcePlayer2ControllerType { get; private set; }

		private void Awake()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ForceControllerType = ((BaseUnityPlugin)this).Config.Bind<ControllerPromptType>("── Controller ──", "Force Controller Prompts", ControllerPromptType.Auto, new ConfigDescription("Force the game to display button prompts for a specific controller type. 'Auto' uses the currently connected controller. In co-op, this applies to Player 1 (Lamb).", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2
				}
			}));
			ForcePlayer2ControllerType = ((BaseUnityPlugin)this).Config.Bind<ControllerPromptType>("── Controller ──", "Force Player 2 Controller Prompts", ControllerPromptType.Auto, new ConfigDescription("Force Player 2 (Goat) to display button prompts for a specific controller type. 'Auto' uses Player 2's currently connected controller. Only applies during co-op.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1
				}
			}));
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "p1xel8ted.cotl.glyphoverride");
			GameObject val = new GameObject("Glyph Override_CoopWatcher");
			val.AddComponent<CoopControllerWatcher>();
			Object.DontDestroyOnLoad((Object)val);
			Log.LogInfo((object)"Glyph Override loaded.");
		}

		internal static InputType? GetForcedInputType(PlayerFarming player = null)
		{
			return (((Object)(object)player != (Object)null && !player.isLamb) ? ForcePlayer2ControllerType.Value : ForceControllerType.Value) switch
			{
				ControllerPromptType.Auto => null, 
				ControllerPromptType.Keyboard => (InputType)1, 
				ControllerPromptType.DualShock4 => (InputType)2, 
				ControllerPromptType.DualSense => (InputType)3, 
				ControllerPromptType.Xbox360 => (InputType)4, 
				ControllerPromptType.XboxOne => (InputType)5, 
				ControllerPromptType.XboxSeries => (InputType)6, 
				ControllerPromptType.SwitchJoyConsDetached => (InputType)7, 
				ControllerPromptType.SwitchJoyConsDocked => (InputType)8, 
				ControllerPromptType.SwitchHandheld => (InputType)9, 
				ControllerPromptType.SwitchProController => (InputType)10, 
				_ => null, 
			};
		}

		internal static bool IsSwitchController(InputType inputType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			if (inputType - 7 <= 3)
			{
				return true;
			}
			return false;
		}
	}
	public enum ControllerPromptType
	{
		Auto,
		Keyboard,
		DualShock4,
		DualSense,
		Xbox360,
		XboxOne,
		XboxSeries,
		SwitchJoyConsDetached,
		SwitchJoyConsDocked,
		SwitchHandheld,
		SwitchProController
	}
	internal static class PlayerContext
	{
		internal static PlayerFarming Current;
	}
	internal class CoopControllerWatcher : MonoBehaviour
	{
		private Controller _lastP2Controller;

		private void Update()
		{
			if (!CoopManager.CoopActive || PlayerFarming.playersCount <= 1 || PlayerFarming.players.Count <= 1)
			{
				return;
			}
			PlayerFarming val = PlayerFarming.players[1];
			if (!((Object)(object)val == (Object)null) && val.rewiredPlayer != null)
			{
				Controller lastActiveController = val.rewiredPlayer.controllers.GetLastActiveController();
				if (lastActiveController != null && lastActiveController != _lastP2Controller)
				{
					_lastP2Controller = lastActiveController;
					InputManager.General.OnActiveControllerChanged?.Invoke(lastActiveController);
				}
			}
		}
	}
	[Harmony]
	public static class Patches
	{
		private const string ButtonA = "\ue900";

		private const string ButtonB = "\ue901";

		private const string ButtonX = "\ue902";

		private const string ButtonY = "\ue903";

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MMControlPrompt), "AssignPrompt")]
		public static void AssignPrompt_Prefix(MMControlPrompt __instance)
		{
			PlayerContext.Current = __instance.playerFarming;
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(MMControlPrompt), "AssignPrompt")]
		public static void AssignPrompt_Finalizer()
		{
			PlayerContext.Current = null;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MMControlPrompt), "ForceUpdate")]
		public static void ForceUpdate_Postfix(MMControlPrompt __instance)
		{
			PlayerFarming playerFarming = __instance.playerFarming;
			if ((Object)(object)playerFarming == (Object)null || playerFarming.rewiredPlayer == null || InputManager.General.GetLastActiveController(playerFarming) != null || InputManager.General.GetDefaultController(playerFarming) != null)
			{
				return;
			}
			foreach (Joystick joystick in playerFarming.rewiredPlayer.controllers.Joysticks)
			{
				if (((Controller)joystick).isConnected && ((Controller)joystick).enabled)
				{
					__instance.OnActiveControllerChanged((Controller)(object)joystick);
					break;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ControlUtilities), "GetCurrentInputType")]
		public static void GetCurrentInputType_Postfix(ref InputType __result)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected I4, but got Unknown
			InputType? forcedInputType = Plugin.GetForcedInputType(PlayerContext.Current);
			if (forcedInputType.HasValue)
			{
				__result = (InputType)(int)forcedInputType.Value;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ControlMappings), "GetControllerCodeFromID")]
		public static void GetControllerCodeFromID_Postfix(int id, ref string __result)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Invalid comparison between Unknown and I4
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Invalid comparison between Unknown and I4
			if (((uint)(id - 4) > 1u && (uint)(id - 7) > 1u) || 1 == 0)
			{
				return;
			}
			InputType currentInputType = ControlUtilities.GetCurrentInputType(InputManager.General.GetLastActiveController(PlayerContext.Current));
			switch (id)
			{
			case 4:
				if (Plugin.IsSwitchController(currentInputType))
				{
					__result = "\ue901";
				}
				break;
			case 5:
				if (Plugin.IsSwitchController(currentInputType))
				{
					__result = "\ue900";
				}
				break;
			case 7:
				__result = (((int)currentInputType == 10) ? "\ue903" : "\ue902");
				break;
			case 8:
				__result = (((int)currentInputType == 10) ? "\ue902" : "\ue903");
				break;
			case 6:
				break;
			}
		}
	}
}
namespace Shared
{
	public static class Helpers
	{
		private static class StorefrontDetector
		{
			private static readonly string[] PiracyFiles = new string[65]
			{
				"SmartSteamEmu.ini", "codex.ini", "steam_emu.ini", "goldberg_emulator.dll", "steamclient_loader.dll", "steam_api64_o.dll", "steam_api.cdx", "steam_api64.cdx.dll", "steam_interfaces.txt", "local_save.txt",
				"valve.ini", "codex64.dll", "coldclient.dll", "ColdClientLoader.ini", "steamless.dll", "GreenLuma", "CreamAPI.dll", "cream_api.ini", "ScreamAPI.dll", "OnlineFix.dll",
				"OnlineFix.url", "online-fix.me", "CODEX", "SKIDROW", "CPY", "PLAZA", "HOODLUM", "EMPRESS", "TENOKE", "PROPHET",
				"REVOLT", "DARKSiDERS", "RAZOR1911", "FLT", "FLT.dll", "RUNE", "RUNE.ini", "TiNYiSO", "RELOADED", "RLD!",
				"DOGE", "BAT", "P2P", "ElAmigos", "FitGirl", "DODI", "xatab", "KaOs", "IGG", "Masquerade",
				"3dmgame.dll", "ALI213.dll", "crack", "crack.exe", "Crack.nfo", "crackfix", "CrackOnly", "fix.exe", "gamefix.dll", "SKIDROW.ini",
				"nosTEAM", "NoSteam", "FCKDRM", "Goldberg", "VALVEEMPRESS"
			};

			public static string DetectStorefront()
			{
				string dir = Directory.GetCurrentDirectory();
				string text = "Unknown";
				if (File.Exists(Path.Combine(dir, "steam_api.dll")) || File.Exists(Path.Combine(dir, "steam_api64.dll")) || File.Exists(Path.Combine(dir, "steam_appid.txt")) || Directory.Exists(Path.Combine(dir, "steam_settings")))
				{
					text = "Steam";
				}
				else if (Directory.GetFiles(dir, "goggame-*.info").Any() || File.Exists(Path.Combine(dir, "galaxy.dll")))
				{
					text = "GOG";
				}
				else if (File.Exists(Path.Combine(dir, "EOSSDK-Win64-Shipping.dll")) || File.Exists(Path.Combine(dir, "EpicOnlineServices.dll")) || Directory.Exists(Path.Combine(dir, ".egstore")))
				{
					text = "Epic";
				}
				else if (IsProcessRunning("steam"))
				{
					text = "Steam (process only)";
				}
				else if (IsProcessRunning("GalaxyClient"))
				{
					text = "GOG (process only)";
				}
				else if (IsProcessRunning("EpicGamesLauncher"))
				{
					text = "Epic (process only)";
				}
				if (PiracyFiles.Any((string pirate) => File.Exists(Path.Combine(dir, pirate)) || Directory.Exists(Path.Combine(dir, pirate))))
				{
					text += " + Possible Pirated/Cracked Files Found!";
				}
				return text;
			}

			private static bool IsProcessRunning(string name)
			{
				return Process.GetProcessesByName(name).Length != 0;
			}
		}

		[CompilerGenerated]
		private sealed class <FilterEnumerator>d__6 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public IEnumerator original;

			public Type[] typesToRemove;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FilterEnumerator>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				while (original.MoveNext())
				{
					object current = original.Current;
					if (current != null && !ArrayExtensions.Contains<Type>(typesToRemove, current.GetType()))
					{
						<>2__current = current;
						<>1__state = 1;
						return true;
					}
				}
				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();
			}
		}

		internal static List<Follower> AllFollowers => FollowerManager.Followers.SelectMany((KeyValuePair<FollowerLocation, List<Follower>> followerList) => followerList.Value).ToList();

		private static bool ContainsIgnoreCase(this string source, string value)
		{
			if (source == null)
			{
				return false;
			}
			return source.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0;
		}

		public static void PrintModLoaded(string plugin, ManualLogSource logger)
		{
			//IL_002a: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			string text = Application.version.Replace("\r", "").Replace("\n", "");
			string buildGUID = Application.buildGUID;
			Platform current = PlatformHelper.Current;
			string text2 = StorefrontDetector.DetectStorefront();
			logger.LogInfo((object)"==========================================");
			logger.LogInfo((object)("  Plugin Loaded: " + plugin));
			logger.LogInfo((object)("  Version   : " + text + " (BuildGUID: " + buildGUID + ")"));
			logger.LogInfo((object)$"  Platform  : {current}");
			logger.LogInfo((object)("  Storefront: " + text2));
			logger.LogInfo((object)"==========================================");
		}

		public static bool IsMultiplierActive(float value)
		{
			return !Mathf.Approximately(value, 1f);
		}

		[IteratorStateMachine(typeof(<FilterEnumerator>d__6))]
		public static IEnumerator FilterEnumerator(IEnumerator original, Type[] typesToRemove)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FilterEnumerator>d__6(0)
			{
				original = original,
				typesToRemove = typesToRemove
			};
		}

		public static void LogCallStack(ManualLogSource logger, int skipFrames = 3, int maxFrames = 10)
		{
			StackTrace stackTrace = new StackTrace(fNeedFileInfo: false);
			int frameCount = stackTrace.FrameCount;
			for (int i = skipFrames; i < frameCount && i < maxFrames; i++)
			{
				MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod();
				logger.LogWarning((object)string.Format(arg1: (methodBase?.DeclaringType)?.FullName, format: "[Frame {0}] {1}.{2}", arg0: i, arg2: methodBase?.Name));
			}
		}

		public static Type GetCallingType(ICollection<Type> targetTypes, int skipFrames = 3, int maxFrames = 10)
		{
			StackTrace stackTrace = new StackTrace(fNeedFileInfo: false);
			int frameCount = stackTrace.FrameCount;
			for (int i = skipFrames; i < frameCount && i < maxFrames; i++)
			{
				Type type = stackTrace.GetFrame(i)?.GetMethod()?.DeclaringType;
				if (type != null && targetTypes.Contains(type))
				{
					return type;
				}
			}
			return null;
		}

		public static bool IsCalledFrom(string typeNameContains, string methodNameContains = null, int skipFrames = 3, int maxFrames = 10)
		{
			StackTrace stackTrace = new StackTrace(fNeedFileInfo: false);
			int frameCount = stackTrace.FrameCount;
			for (int i = skipFrames; i < frameCount && i < maxFrames; i++)
			{
				MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod();
				Type type = methodBase?.DeclaringType;
				if (!(type == null))
				{
					bool num = type.FullName.ContainsIgnoreCase(typeNameContains);
					bool flag = methodNameContains == null || methodBase.Name.ContainsIgnoreCase(methodNameContains);
					if (num && flag)
					{
						return true;
					}
				}
			}
			return false;
		}
	}
}