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.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1")]
[assembly: AssemblyProduct("com.github.Kirshoo.ScoutBadger")]
[assembly: AssemblyTitle("ScoutBadger")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.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.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 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.1.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.1.1";
private void Awake()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
BindConfig();
SaveManager = new SaveManager(SaveConfig.SafeFile);
SaveManager.Load();
Harmony val = new Harmony("com.github.Kirshoo.ScoutBadger");
val.PatchAll(typeof(AchievementManagerPatch));
val.PatchAll(typeof(EndScreenPatch.BadgeRoutinePatch));
val.PatchAll(typeof(BadgeUIPatch));
Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
}
private void OnApplicationQuit()
{
SaveManager.Save();
}
private void BindConfig()
{
SaveConfig.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<TextMeshProUGUI>();
((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<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((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<TMP_FontAsset>("LiberationSans SDF.asset");
}
fontAsset = val;
return fontAsset;
}
public void UpdateCount(int newCount)
{
if (newCount < 2)
{
((TMP_Text)textComponent).text = "";
}
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<BadgeEntry> entries = new List<BadgeEntry>();
}
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<BadgeSaveData>(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<ACHIEVEMENTTYPE> repeatedAchievements = new List<ACHIEVEMENTTYPE>();
public static AchievementContext Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
_instance = new AchievementContext();
}
}
return _instance;
}
}
}
internal class AchievementManagerPatch
{
[HarmonyPatch(typeof(AchievementManager), "ThrowAchievement")]
[HarmonyPostfix]
private static void AddToEarnedAchievements(AchievementManager __instance, ACHIEVEMENTTYPE type)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
if (!__instance.runBasedValueData.achievementsEarnedThisRun.Contains(type))
{
__instance.runBasedValueData.achievementsEarnedThisRun.Add(type);
}
}
[HarmonyPatch(typeof(AchievementManager), "ThrowAchievement")]
[HarmonyPrefix]
private static void AddRepeatedAchievements(AchievementManager __instance, ACHIEVEMENTTYPE type)
{
//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_002f: 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)
if (__instance.runBasedValueData.steamAchievementsPreviouslyUnlocked.Contains(type) && !AchievementContext.Instance.repeatedAchievements.Contains(type))
{
AchievementContext.Instance.repeatedAchievements.Add(type);
Plugin.SaveManager.IncrementBadgeRepetition(type);
}
}
}
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<RectTransform>();
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("<BadgeRoutine>"));
return AccessTools.Method(type, "MoveNext", (Type[])null, (Type[])null);
}
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
{
int num = -1;
int num2 = -1;
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(Singleton<Customization>), "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<CodeInstruction> list2 = null;
try
{
list2 = new List<CodeInstruction>(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<CodeInstruction> collection = new List<CodeInstruction>(CreateIsRepeatedCheck(list2, label));
List<CodeInstruction> list3 = null;
try
{
list3 = new List<CodeInstruction>(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<CodeInstruction> list4 = new List<CodeInstruction>(CreateAdditionalRepeatedCrownCheck(list3, escapeLabel));
list.InsertRange(num2 + 10, list4);
list.InsertRange(num + list4.Count, collection);
return list;
}
private static CodeInstruction FindEndOfCosmeticLoop(List<CodeInstruction> instructions, int startIdx = 0)
{
MethodInfo methodInfo = AccessTools.Method(typeof(List<CustomizationOption>).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<CodeInstruction> instructions, int index = 0)
{
MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(List<ACHIEVEMENTTYPE>), "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<CodeInstruction> GetLoadBadgeDataSequence(List<CodeInstruction> instructions, int startIdx = 0)
{
MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(List<BadgeData>), "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<CodeInstruction> GetCrownCheckLoadCurrentAchievementSequence(List<CodeInstruction> 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<CodeInstruction> CreateAdditionalRepeatedCrownCheck(IEnumerable<CodeInstruction> 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<ACHIEVEMENTTYPE>), "Contains", new Type[1] { typeof(ACHIEVEMENTTYPE) }, (Type[])null);
return ((IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
{
new CodeInstruction(OpCodes.Call, (object)methodInfo),
new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo)
}).Concat(currentAchievement).Concat((IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
{
new CodeInstruction(OpCodes.Callvirt, (object)methodInfo2),
new CodeInstruction(OpCodes.Brtrue, (object)escapeLabel)
});
}
private static IEnumerable<CodeInstruction> CreateIsRepeatedCheck(IEnumerable<CodeInstruction> 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<ACHIEVEMENTTYPE>), "Contains", new Type[1] { typeof(ACHIEVEMENTTYPE) }, (Type[])null);
return badgeDataSeq.Concat((IEnumerable<CodeInstruction>)(object)new CodeInstruction[3]
{
new CodeInstruction(OpCodes.Ldnull, (object)null),
new CodeInstruction(OpCodes.Ceq, (object)null),
new CodeInstruction(OpCodes.Brtrue, (object)escapeLabel)
}).Concat((IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
{
new CodeInstruction(OpCodes.Call, (object)methodInfo),
new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo)
}).Concat(badgeDataSeq)
.Concat((IEnumerable<CodeInstruction>)(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<string> _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<string>("SaveData", "CustomFilepath", "", "Optional. Overrides default save location.");
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}