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;
}
}
}