using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; 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 Microsoft.CodeAnalysis; using Newtonsoft.Json; using ScoutBadger.Configuration; using ScoutBadger.Patches; using ScoutBadger.Saves; using ScoutBadger.UIHelpers; using TMPro; using UnityEngine; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.Kirshoo.ScoutBadger")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.3.1.0")] [assembly: AssemblyInformationalVersion("1.3.1")] [assembly: AssemblyProduct("com.github.Kirshoo.ScoutBadger")] [assembly: AssemblyTitle("ScoutBadger")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.1.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 BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace ScoutBadger { [BepInPlugin("com.github.Kirshoo.ScoutBadger", "ScoutBadger", "1.3.1")] public class Plugin : BaseUnityPlugin { internal static SaveManager SaveManager; public const string Id = "com.github.Kirshoo.ScoutBadger"; internal static ManualLogSource Log { get; private set; } public static string Name => "ScoutBadger"; public static string Version => "1.3.1"; private bool IsCompatible(BuildVersion version) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (version.MajorVersion == 1) { return version.MinorVersion >= 60; } return false; } private void Awake() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; BuildVersion val = default(BuildVersion); ((BuildVersion)(ref val))..ctor(Application.version, "???"); Log.LogDebug((object)$"Running on version {val}"); if (!IsCompatible(val)) { Log.LogError((object)("Incompatible version of the game detected. " + Name + " v" + Version + " will be disabled.")); } else { BindConfig(); SaveManager = new SaveManager(SaveConfig.SafeFile); SaveManager.Load(); Harmony val2 = new Harmony("com.github.Kirshoo.ScoutBadger"); val2.PatchAll(typeof(AchievementManagerPatch)); val2.PatchAll(typeof(EndScreenPatch.BadgeRoutinePatch)); val2.PatchAll(typeof(BadgeUIPatch)); Log.LogInfo((object)("Plugin " + Name + " is loaded!")); } } private void OnApplicationQuit() { SaveManager.Save(); } private void BindConfig() { SaveConfig.BindConfig(((BaseUnityPlugin)this).Config); VisualConfig.BindConfig(((BaseUnityPlugin)this).Config); } } } namespace ScoutBadger.UIHelpers { internal class BadgeRepetitionText { private static TMP_FontAsset fontAsset; private const string fontname = "DarumaDropOne-Regular SDF"; public const string RepetitionObjectName = "RepetitionText"; public GameObject gameObject; private TextMeshProUGUI textComponent; private BadgeRepetitionText() { } public static BadgeRepetitionText CreateTextObject() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown BadgeRepetitionText badgeRepetitionText = new BadgeRepetitionText(); GameObject val = new GameObject("RepetitionText"); TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).font = LoadFont(); ((TMP_Text)val2).text = ""; ((TMP_Text)val2).fontSizeMax = 40f; ((TMP_Text)val2).fontSizeMin = 18f; ((TMP_Text)val2).horizontalAlignment = (HorizontalAlignmentOptions)4; badgeRepetitionText.gameObject = val; badgeRepetitionText.textComponent = val2; return badgeRepetitionText; } private static TMP_FontAsset LoadFont() { if ((Object)(object)fontAsset != (Object)null) { return fontAsset; } TMP_FontAsset val = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((TMP_FontAsset asset) => ((Object)asset).name == "DarumaDropOne-Regular SDF")); if ((Object)(object)val == (Object)null) { Plugin.Log.LogDebug((object)"Unable to load DarumaDropOne-Regular SDF! Falling back to default font."); val = Resources.GetBuiltinResource("LiberationSans SDF.asset"); } fontAsset = val; return fontAsset; } public void UpdateCount(int newCount) { if (newCount < 2) { ((TMP_Text)textComponent).text = ""; return; } if (newCount > 99) { newCount = 99; } ((TMP_Text)textComponent).text = $"x{newCount}"; } } } namespace ScoutBadger.Saves { [Serializable] public class BadgeEntry { public ACHIEVEMENTTYPE LinkedAchievement; public int ReceivedAmount; public DateTime FirstAcquiredAt; public DateTime LastAcquiredAt; } [Serializable] public class BadgeSaveData { public int version = 1; public List entries = new List(); } internal class SaveManager { private BadgeSaveData? saveData; private string? filepath; public SaveManager(string filepath) { SetSavePath(filepath); } public void SetSavePath(string path) { if (string.IsNullOrEmpty(path)) { Plugin.Log.LogWarning((object)"Provided save path is null or empty"); } filepath = path; } public void Load() { if (string.IsNullOrEmpty(filepath)) { throw new ArgumentException("Save path is not set. Call SetSavePath() first."); } if (!File.Exists(filepath)) { saveData = new BadgeSaveData(); return; } BadgeSaveData badgeSaveData = JsonConvert.DeserializeObject(File.ReadAllText(filepath)); if (badgeSaveData == null) { Plugin.Log.LogWarning((object)"Unable to load badge save data. Falling back to default info."); saveData = new BadgeSaveData(); } else { saveData = badgeSaveData; } } public void Save() { if (string.IsNullOrEmpty(filepath)) { throw new ArgumentException("Save path is not set. Call SetSavePath() first."); } if (saveData == null) { Plugin.Log.LogWarning((object)"Ignoring attempt to save uninitialized data"); return; } string contents = JsonConvert.SerializeObject((object)saveData, (Formatting)0); Directory.CreateDirectory(Path.GetDirectoryName(filepath)); File.WriteAllText(filepath, contents); } public void IncrementBadgeRepetition(ACHIEVEMENTTYPE type) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (saveData == null) { throw new InvalidOperationException("Save data is not initialized. Call Load() first."); } if (!TryGetBadge(type, out BadgeEntry badgeEntry)) { badgeEntry = new BadgeEntry { LinkedAchievement = type, ReceivedAmount = 0 }; saveData.entries.Add(badgeEntry); } DateTime now = DateTime.Now; if (badgeEntry.ReceivedAmount == 0) { badgeEntry.FirstAcquiredAt = now; } badgeEntry.LastAcquiredAt = now; badgeEntry.ReceivedAmount++; } public bool TryGetBadge(ACHIEVEMENTTYPE type, out BadgeEntry badgeEntry) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) badgeEntry = GetBadge(type); if (badgeEntry == null) { return false; } return true; } public BadgeEntry? GetBadge(ACHIEVEMENTTYPE type) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (saveData == null) { throw new InvalidOperationException("Save data is not initialized. Call Load() first."); } return saveData.entries.Find((BadgeEntry entry) => entry.LinkedAchievement == type); } } } namespace ScoutBadger.Patches { internal class AchievementContext { private static AchievementContext _instance = null; private static readonly object _lock = new object(); internal List repeatedAchievements = new List(); public static AchievementContext Instance { get { if (_instance == null) { lock (_lock) { _instance = new AchievementContext(); } } return _instance; } } } internal class AchievementManagerPatch { private static readonly List steamStatAchievements = new List { new SteamStatBasedAchievementData((ACHIEVEMENTTYPE)29, (STEAMSTATTYPE)5, 5000), new SteamStatBasedAchievementData((ACHIEVEMENTTYPE)7, (STEAMSTATTYPE)2, 5), new SteamStatBasedAchievementData((ACHIEVEMENTTYPE)6, (STEAMSTATTYPE)1, 20), new SteamStatBasedAchievementData((ACHIEVEMENTTYPE)9, (STEAMSTATTYPE)4, 200), new SteamStatBasedAchievementData((ACHIEVEMENTTYPE)8, (STEAMSTATTYPE)3, 10) }; private static bool CanAwardAchievement() { if (RunSettings.blockingAchievements) { return VisualConfig.ShowBadgesInCustomRuns; } return true; } private static bool IsCustomRun() { if (!RunSettings.IsCustomRun) { return RunSettings.isMiniRun; } return true; } [HarmonyPatch(typeof(AchievementManager), "ThrowAchievement")] [HarmonyPostfix] private static void AddToEarnedAchievements(AchievementManager __instance, ACHIEVEMENTTYPE type) { //IL_0001: 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) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!__instance.runBasedValueData.achievementsEarnedThisRun.Contains(type) && CanAwardAchievement()) { __instance.runBasedValueData.achievementsEarnedThisRun.Add(type); } } [HarmonyPatch(typeof(AchievementManager), "ThrowAchievement")] [HarmonyPrefix] private static void AddRepeatedAchievements(AchievementManager __instance, ACHIEVEMENTTYPE type) { //IL_0001: 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) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (__instance.runBasedValueData.steamAchievementsPreviouslyUnlocked.Contains(type) && !AchievementContext.Instance.repeatedAchievements.Contains(type) && CanAwardAchievement()) { Plugin.Log.LogDebug((object)$"Awarding {type} achievement!"); AchievementContext.Instance.repeatedAchievements.Add(type); if (!IsCustomRun()) { Plugin.SaveManager.IncrementBadgeRepetition(type); } } } [HarmonyPatch(typeof(AchievementManager), "IncrementSteamStat")] [HarmonyPostfix] private static void AddSteamStatAchievementRepeat(AchievementManager __instance, int __result, STEAMSTATTYPE steamStatType, int value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_007a: Unknown result type (might be due to invalid IL or missing references) if (!GetAchievementStatData(__instance, steamStatType, out SteamStatBasedAchievementData achievement)) { Plugin.Log.LogDebug((object)$"Unable to find achievement data for {steamStatType}"); return; } if (AchievementContext.Instance.repeatedAchievements.Contains(achievement.achievementType)) { Plugin.Log.LogDebug((object)$"Achievement {achievement.achievementType} is already been achieved."); return; } int num = (__result - value) / achievement.requiredValue; int num2 = __result / achievement.requiredValue; if (num2 > num) { __instance.ThrowAchievement(achievement.achievementType); } } private static bool GetAchievementStatData(AchievementManager manager, STEAMSTATTYPE steamStatType, out SteamStatBasedAchievementData achievement) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_003a: Unknown result type (might be due to invalid IL or missing references) achievement = new SteamStatBasedAchievementData((ACHIEVEMENTTYPE)0, (STEAMSTATTYPE)0, 1); SteamStatBasedAchievementData achievementData = default(SteamStatBasedAchievementData); foreach (object value in Enum.GetValues(typeof(ACHIEVEMENTTYPE))) { ACHIEVEMENTTYPE val = (ACHIEVEMENTTYPE)value; if ((manager.TryGetSteamStatLinkedAchievement(val, ref achievementData) || TryGetSteamStatAchievement(val, out achievementData)) && achievementData.statType == steamStatType) { achievement = achievementData; return true; } } return false; } private static bool TryGetSteamStatAchievement(ACHIEVEMENTTYPE achievement, out SteamStatBasedAchievementData achievementData) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) achievementData = new SteamStatBasedAchievementData((ACHIEVEMENTTYPE)0, (STEAMSTATTYPE)0, 1); foreach (SteamStatBasedAchievementData steamStatAchievement in steamStatAchievements) { if (steamStatAchievement.achievementType == achievement) { achievementData = steamStatAchievement; return true; } } return false; } } internal class BadgeUIPatch { [HarmonyPatch(typeof(BadgeUI), "Init")] [HarmonyPostfix] private static void CreateRepetitionText(BadgeUI __instance) { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_00d9: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)((Component)__instance).transform.Find("RepetitionText")) && !(((Object)((Component)__instance).transform.parent).name == "Grid") && !((Object)(object)__instance.data == (Object)null)) { BadgeRepetitionText badgeRepetitionText = BadgeRepetitionText.CreateTextObject(); badgeRepetitionText.gameObject.transform.SetParent(((Component)__instance).gameObject.transform, false); RectTransform component = badgeRepetitionText.gameObject.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { component.anchorMin = new Vector2(0f, 0.5f); component.anchorMax = new Vector2(1f, 0.5f); component.anchoredPosition = new Vector2(0f, -15f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(0f, 50f); } BadgeEntry badge = Plugin.SaveManager.GetBadge(__instance.data.linkedAchievement); if (badge != null) { badgeRepetitionText.UpdateCount(badge.ReceivedAmount); } } } } internal class EndScreenPatch { [HarmonyPatch] public static class BadgeRoutinePatch { private const int crownCheckLength = 10; private const int crownCheckNextIterationLabelOffset = 4; private const int illegalIndex = -1; private static MethodBase TargetMethod() { Type type = typeof(EndScreen).GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((Type t) => t.Name.Contains("")); return AccessTools.Method(type, "MoveNext", (Type[])null, (Type[])null); } private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator il) { int num = -1; int num2 = -1; List list = new List(instructions); MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(Singleton), "Instance"); for (int i = 0; i < list.Count - 4; i++) { if (list[i].opcode == OpCodes.Call && (MethodInfo)list[i].operand == methodInfo && list[i + 1].opcode == OpCodes.Ldarg_0 && list[i + 4].opcode == OpCodes.Ldfld && list[i + 4].operand != null && num == -1) { num = i; } if (IsCrownCheck(list, i) && num2 == -1) { num2 = i; } } if (num == -1) { Plugin.Log.LogError((object)"[Transpiler] Unable to find Cosmetic loading instructions"); return instructions; } if (num2 == -1) { Plugin.Log.LogError((object)"[Transpiler] Unable to find unlock crown check instructions"); return instructions; } List list2 = null; try { list2 = new List(GetLoadBadgeDataSequence(list)); } catch (InvalidOperationException ex) { Plugin.Log.LogError((object)("[Transpiler] Loading Badge Data sequence: " + ex.Message)); return instructions; } Label label = il.DefineLabel(); try { CodeInstruction val = FindEndOfCosmeticLoop(list); val.labels.Add(label); } catch (InvalidOperationException ex2) { Plugin.Log.LogError((object)("[Transpiler] Looking for end of cosmetic routine: " + ex2.Message)); return instructions; } List collection = new List(CreateIsRepeatedCheck(list2, label)); List list3 = null; try { list3 = new List(GetCrownCheckLoadCurrentAchievementSequence(list, num2 + 4)); } catch (InvalidOperationException ex3) { Plugin.Log.LogError((object)("[Transpiler] Loading Crown Check sequence: " + ex3.Message)); return instructions; } Label escapeLabel = (Label)list[num2 + 4].operand; List list4 = new List(CreateAdditionalRepeatedCrownCheck(list3, escapeLabel)); list.InsertRange(num2 + 10, list4); list.InsertRange(num + list4.Count, collection); return list; } private static CodeInstruction FindEndOfCosmeticLoop(List instructions, int startIdx = 0) { MethodInfo methodInfo = AccessTools.Method(typeof(List).GetNestedType("Enumerator"), "MoveNext", (Type[])null, (Type[])null); for (int i = startIdx; i < instructions.Count - 6; i++) { if (instructions[i].opcode == OpCodes.Ldarg_0 && instructions[i + 2].opcode == OpCodes.Call && instructions[i + 3].opcode == OpCodes.Brtrue && instructions[i + 4].opcode == OpCodes.Ldarg_0 && instructions[i + 6].opcode == OpCodes.Ldarg_0) { return instructions[i + 6]; } } throw new InvalidOperationException("Unable to find end of the cosmetics loop"); } private static bool IsCrownCheck(List instructions, int index = 0) { MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(List), "Item"); if (index >= 0 && index + 2 < instructions.Count && instructions[index].opcode == OpCodes.Ldloc_3 && instructions[index + 1].opcode == OpCodes.Ldloc_S && instructions[index + 2].opcode == OpCodes.Callvirt) { return (MethodInfo)instructions[index + 2].operand == methodInfo; } return false; } private static IEnumerable GetLoadBadgeDataSequence(List instructions, int startIdx = 0) { MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(List), "Item"); for (int i = startIdx; i < instructions.Count - 5; i++) { if (instructions[i].opcode == OpCodes.Ldarg_0 && instructions[i + 2].opcode == OpCodes.Ldarg_0 && instructions[i + 4].opcode == OpCodes.Callvirt && (MethodInfo)instructions[i + 4].operand == methodInfo) { return instructions.GetRange(i, 5); } } throw new InvalidOperationException("Unable to find BadgeData loader"); } private static IEnumerable GetCrownCheckLoadCurrentAchievementSequence(List instructions, int startIdx) { for (int i = startIdx; i < instructions.Count - 2; i++) { if (IsCrownCheck(instructions, i)) { return instructions.GetRange(i, 3); } } throw new InvalidOperationException("Unable to find CurrentAchievement loader"); } private static IEnumerable CreateAdditionalRepeatedCrownCheck(IEnumerable currentAchievement, Label escapeLabel) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(AchievementContext), "Instance"); FieldInfo fieldInfo = AccessTools.Field(typeof(AchievementContext), "repeatedAchievements"); MethodInfo methodInfo2 = AccessTools.Method(typeof(List), "Contains", new Type[1] { typeof(ACHIEVEMENTTYPE) }, (Type[])null); return ((IEnumerable)(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Call, (object)methodInfo), new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo) }).Concat(currentAchievement).Concat((IEnumerable)(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Callvirt, (object)methodInfo2), new CodeInstruction(OpCodes.Brtrue, (object)escapeLabel) }); } private static IEnumerable CreateIsRepeatedCheck(IEnumerable badgeDataSeq, Label escapeLabel) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(AchievementContext), "Instance"); FieldInfo fieldInfo = AccessTools.Field(typeof(AchievementContext), "repeatedAchievements"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(BadgeData), "linkedAchievement"); MethodInfo methodInfo2 = AccessTools.Method(typeof(List), "Contains", new Type[1] { typeof(ACHIEVEMENTTYPE) }, (Type[])null); return badgeDataSeq.Concat((IEnumerable)(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldnull, (object)null), new CodeInstruction(OpCodes.Ceq, (object)null), new CodeInstruction(OpCodes.Brtrue, (object)escapeLabel) }).Concat((IEnumerable)(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Call, (object)methodInfo), new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo) }).Concat(badgeDataSeq) .Concat((IEnumerable)(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo2), new CodeInstruction(OpCodes.Callvirt, (object)methodInfo2), new CodeInstruction(OpCodes.Brtrue, (object)escapeLabel) }); } } } } namespace ScoutBadger.Configuration { internal static class SaveConfig { private static readonly string defaultSavefile = Path.Combine(Paths.ConfigPath, "ScoutBadger", "badges.json"); private static ConfigEntry _customSavefile = null; public static string SafeFile { get { if (_customSavefile == null) { throw new InvalidOperationException("SaveConfig is not bound to a config file"); } string value = defaultSavefile; if (_customSavefile.Value != "") { value = _customSavefile.Value; } return value; } } public static void BindConfig(ConfigFile config) { _customSavefile = config.Bind("SaveData", "CustomFilepath", "", "Optional. Overrides default save location."); } } internal class VisualConfig { private static ConfigEntry showBadgesInCustom; public static bool ShowBadgesInCustomRuns { get { if (showBadgesInCustom == null) { throw new InvalidOperationException("SaveConfig is not bound to a config file"); } return showBadgesInCustom.Value; } } public static void BindConfig(ConfigFile config) { showBadgesInCustom = config.Bind("Visual", "ShowBadgesInCustomRuns", true, "Show badges obtained during a Mini/Custom run"); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }