Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Loot Topup v1.2.3
LootTopup.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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 Microsoft.CodeAnalysis; using Photon.Pun; using REPOLib.Modules; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("LootTopup")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("LootTopup")] [assembly: AssemblyTitle("LootTopup")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 LootTopup { [BepInPlugin("themorningstar.loottopup", "Loot Topup", "1.2.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal struct SpawnSpot { public Vector3 position; public Quaternion rotation; public Type type; } internal struct TemplateInfo { public GameObject prefab; public string resourceId; public PrefabRef repoLibRef; public float value; public Type volumeType; } public const string Guid = "themorningstar.loottopup"; internal static ManualLogSource Log = null; internal static ConfigEntry<float> TargetMultiplier; internal static ConfigEntry<int> MinValuables; internal static ConfigEntry<bool> WatchdogEnabled; internal static ConfigEntry<float> WatchdogInterval; internal static ConfigEntry<bool> RespectHuntingSeason; internal static ConfigEntry<string> SkipMutatorNames; internal static ConfigEntry<int> MaxSpawnsPerLevel; internal static bool ToppedUpThisLevel; internal static int SpawnedThisLevel; internal static readonly List<TemplateInfo> Templates = new List<TemplateInfo>(); internal static bool Busy; internal static readonly HashSet<string> SpawnBlacklist = new HashSet<string>(); internal static readonly List<SpawnSpot> Spots = new List<SpawnSpot>(); internal static List<TemplateInfo> PresetTemplates; internal static bool WarnedNoTemplates; internal static bool WarnedNoSpots; private void Awake() { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; TargetMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Topup", "TargetMultiplier", 1.3f, "Top up until achievable value is at least haulGoal * this. 1.0 = exactly completable; 1.3 = 30% buffer."); MinValuables = ((BaseUnityPlugin)this).Config.Bind<int>("Topup", "MinValuables", 8, "Guarantee at least this many valuables on the map at level start (anti-fragility for sparse maps). 0 disables."); WatchdogEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Watchdog", "Enabled", true, "Detect mid-level softlocks (too much value destroyed to finish) and top up so the run stays winnable."); WatchdogInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Watchdog", "IntervalSeconds", 4f, "How often the watchdog re-checks completability during a level."); RespectHuntingSeason = ((BaseUnityPlugin)this).Config.Bind<bool>("Mutators", "RespectNoLootMutators", true, "Skip all topup when a mutator that intentionally removes loot (e.g. Hunting Season) is active."); SkipMutatorNames = ((BaseUnityPlugin)this).Config.Bind<string>("Mutators", "SkipMutatorNames", "Hunting Season", "Comma-separated mutator display names during which topup is disabled."); MaxSpawnsPerLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Topup", "MaxSpawnsPerLevel", 60, "Hard cap on how many valuables this mod will spawn in a single level (runaway guard). Failed spawns also count toward this cap."); try { new Harmony("themorningstar.loottopup").PatchAll(); Log.LogInfo((object)"LootTopup: armed (min-count floor + mid-level softlock watchdog; respects no-loot mutators)."); } catch (Exception ex) { Log.LogError((object)("LootTopup: patch failed: " + ex)); } } } [HarmonyPatch(typeof(LevelGenerator), "Start")] internal static class ResetGuardPatch { [HarmonyPrefix] private static void Prefix() { Plugin.ToppedUpThisLevel = false; Plugin.SpawnedThisLevel = 0; Plugin.Templates.Clear(); Plugin.SpawnBlacklist.Clear(); Plugin.Spots.Clear(); Plugin.PresetTemplates = null; Plugin.WarnedNoTemplates = false; Plugin.WarnedNoSpots = false; Plugin.Busy = false; } } [HarmonyPatch(typeof(ValuableVolume), "Setup")] internal static class CaptureSpotsPatch { [HarmonyPrefix] private static void Prefix(ValuableVolume __instance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && ((Behaviour)__instance).isActiveAndEnabled) { Plugin.Spots.Add(new Plugin.SpawnSpot { position = ((Component)__instance).transform.position, rotation = ((Component)__instance).transform.rotation, type = __instance.VolumeType }); } } } [HarmonyPatch(typeof(ValuablePropSwitch), "Setup")] internal static class DropPropSpotsPatch { [HarmonyPostfix] private static void Postfix(ValuablePropSwitch __instance) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.ValuableParent == (Object)null || __instance.ValuableParent.activeSelf) { return; } ValuableVolume componentInChildren = ((Component)__instance).GetComponentInChildren<ValuableVolume>(true); if (!((Object)(object)componentInChildren == (Object)null)) { Vector3 p = ((Component)componentInChildren).transform.position; Plugin.Spots.RemoveAll(delegate(Plugin.SpawnSpot s) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) Vector3 val = s.position - p; return ((Vector3)(ref val)).sqrMagnitude < 0.01f; }); } } } [HarmonyPatch(typeof(RoundDirector), "StartRoundLogic")] internal static class StartPatch { [HarmonyPostfix] private static void Postfix(RoundDirector __instance) { if (!Plugin.ToppedUpThisLevel && SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.RunIsLevel()) { Plugin.ToppedUpThisLevel = true; ((MonoBehaviour)__instance).StartCoroutine(Driver(__instance)); } } private static IEnumerator Driver(RoundDirector rd) { yield return (object)new WaitForSeconds(2.5f); TopupLogic.CaptureTemplates(); TopupLogic.Evaluate(rd, "level start"); if (!Plugin.WatchdogEnabled.Value) { yield break; } WaitForSeconds wait = new WaitForSeconds(Mathf.Max(1f, Plugin.WatchdogInterval.Value)); while ((Object)(object)rd != (Object)null && SemiFunc.RunIsLevel()) { yield return wait; if ((Object)(object)rd == (Object)null || !SemiFunc.RunIsLevel()) { break; } TopupLogic.Evaluate(rd, "watchdog"); } } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "BreakRPC")] internal static class BreakTriggerPatch { [HarmonyPostfix] private static void Postfix() { if (Plugin.WatchdogEnabled.Value && SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.RunIsLevel()) { RoundDirector instance = RoundDirector.instance; if ((Object)(object)instance != (Object)null) { TopupLogic.Evaluate(instance, "item damaged"); } } } } internal static class TopupLogic { private static Type _mutatorManagerType; private static bool _mutatorLookupDone; private const float SpotClearRadius = 1f; private static IEnumerable<ValuableObject> LiveValuables() { ValuableDirector instance = ValuableDirector.instance; if ((Object)(object)instance != (Object)null && instance.valuableList != null) { return instance.valuableList; } return Object.FindObjectsOfType<ValuableObject>(); } public static void CaptureTemplates() { Plugin.Templates.Clear(); foreach (ValuableObject item in LiveValuables()) { if (!((Object)(object)item == (Object)null)) { GameObject gameObject = ((Component)item).gameObject; if (!((Object)(object)gameObject == (Object)null)) { Plugin.Templates.Add(MakeTemplate(gameObject, item.dollarValueCurrent)); } } } } private static Plugin.TemplateInfo MakeTemplate(GameObject go, float value) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) string text = "Valuables/" + ((Object)go).name.Replace("(Clone)", "").Trim(); PrefabRef repoLibRef = default(PrefabRef); NetworkPrefabs.TryGetNetworkPrefabRef(text, ref repoLibRef); ValuableObject component = go.GetComponent<ValuableObject>(); return new Plugin.TemplateInfo { prefab = go, resourceId = text, repoLibRef = repoLibRef, value = value, volumeType = (Type)((!((Object)(object)component != (Object)null)) ? 2 : ((int)component.volumeType)) }; } private static List<Plugin.TemplateInfo> PresetTemplates() { List<Plugin.TemplateInfo> list = FromPresets(((Object)(object)LevelGenerator.Instance != (Object)null && (Object)(object)LevelGenerator.Instance.Level != (Object)null) ? LevelGenerator.Instance.Level.ValuablePresets : null); string arg = "this level's presets"; if (list.Count == 0 && (Object)(object)RunManager.instance != (Object)null && RunManager.instance.levels != null) { list = FromPresets(RunManager.instance.levels.Where((Level l) => (Object)(object)l != (Object)null && l.ValuablePresets != null).SelectMany((Level l) => l.ValuablePresets)); arg = "all run levels' presets"; } list = (from t in list group t by t.resourceId into g select g.First()).ToList(); Plugin.Log.LogInfo((object)$"LootTopup: no live valuables to copy; using {list.Count} valuable prefab(s) from {arg}."); return list; } private static List<Plugin.TemplateInfo> FromPresets(IEnumerable<LevelValuables> presets) { List<Plugin.TemplateInfo> result = new List<Plugin.TemplateInfo>(); if (presets == null) { return result; } foreach (LevelValuables preset in presets) { if (!((Object)(object)preset == (Object)null)) { Add(result, preset.tiny, (Type)0); Add(result, preset.small, (Type)1); Add(result, preset.medium, (Type)2); Add(result, preset.big, (Type)3); Add(result, preset.wide, (Type)4); Add(result, preset.tall, (Type)5); Add(result, preset.veryTall, (Type)6); } } return result; } private static void Add(List<Plugin.TemplateInfo> result, List<PrefabRef> refs, Type type) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if (refs == null) { return; } foreach (PrefabRef @ref in refs) { if (@ref != null && ((PrefabRef<GameObject>)(object)@ref).IsValid() && !string.IsNullOrEmpty(((PrefabRef<GameObject>)(object)@ref).ResourcePath)) { GameObject prefab = ((PrefabRef<GameObject>)(object)@ref).Prefab; if (!((Object)(object)prefab == (Object)null)) { result.Add(new Plugin.TemplateInfo { prefab = prefab, resourceId = ((PrefabRef<GameObject>)(object)@ref).ResourcePath, repoLibRef = null, value = 0f, volumeType = type }); } } } } private static bool SpotTaken(Vector3 spot, List<Vector3> reserved, List<ValuableObject> live) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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) float num = 1f; Vector3 val; for (int i = 0; i < reserved.Count; i++) { val = reserved[i] - spot; if (((Vector3)(ref val)).sqrMagnitude < num) { return true; } } for (int j = 0; j < live.Count; j++) { ValuableObject val2 = live[j]; if (!((Object)(object)val2 == (Object)null)) { val = ((Component)val2).transform.position - spot; if (((Vector3)(ref val)).sqrMagnitude < num) { return true; } } } return false; } private static bool TryPickSpot(Type preferred, List<Vector3> reserved, List<ValuableObject> live, out Vector3 pos, out Quaternion rot) { //IL_0001: 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) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected I4, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) pos = default(Vector3); rot = Quaternion.identity; if (Plugin.Spots.Count == 0) { return false; } List<Plugin.SpawnSpot> list = new List<Plugin.SpawnSpot>(); int num = int.MaxValue; for (int i = 0; i < Plugin.Spots.Count; i++) { Plugin.SpawnSpot item = Plugin.Spots[i]; bool flag = SpotTaken(item.position, reserved, live); int num2 = item.type - preferred; int num3 = ((flag || num2 != 0) ? ((!flag && num2 > 0) ? 1 : ((flag && num2 == 0) ? 2 : (flag ? 4 : 3))) : 0); if (num3 < num) { num = num3; list.Clear(); list.Add(item); } else if (num3 == num) { list.Add(item); } } Plugin.SpawnSpot spawnSpot = list[Random.Range(0, list.Count)]; pos = spawnSpot.position; rot = spawnSpot.rotation; if (num >= 2 && SpotTaken(spawnSpot.position, reserved, live)) { pos += Vector3.up * 0.7f; } return true; } private static GameObject TrySpawn(Plugin.TemplateInfo tmpl, bool mp, Vector3 pos, Quaternion rot) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!mp) { return Object.Instantiate<GameObject>(tmpl.prefab, pos, rot); } if (tmpl.repoLibRef != null) { return NetworkPrefabs.SpawnNetworkPrefab(tmpl.repoLibRef, pos, rot, (byte)0, (object[])null); } return PhotonNetwork.InstantiateRoomObject(tmpl.resourceId, pos, rot, (byte)0, (object[])null); } public static void Evaluate(RoundDirector rd, string reason) { //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) if (Plugin.Busy || (Object)(object)rd == (Object)null) { return; } int haulGoal = rd.haulGoal; if (haulGoal <= 0 || Plugin.SpawnedThisLevel >= Plugin.MaxSpawnsPerLevel.Value || (Plugin.RespectHuntingSeason.Value && NoLootMutatorActive())) { return; } List<ValuableObject> list = (from v in LiveValuables() where (Object)(object)v != (Object)null select v).ToList(); int count = list.Count; float num = 0f; for (int num2 = 0; num2 < list.Count; num2++) { num += list[num2].dollarValueCurrent; } int num3 = Mathf.Max(1, rd.extractionPoints); float num4 = (float)haulGoal / (float)num3; float num5 = (float)rd.extractionPointsCompleted * num4; float num6 = num + num5; float num7 = (float)haulGoal * Plugin.TargetMultiplier.Value; int value = Plugin.MinValuables.Value; bool num8 = num6 < num7; bool flag = count < value; if (!num8 && !flag) { return; } List<Plugin.TemplateInfo> source = ((Plugin.Templates.Count > 0) ? Plugin.Templates : list.Select((ValuableObject v) => MakeTemplate(((Component)v).gameObject, v.dollarValueCurrent)).ToList()); source = source.Where((Plugin.TemplateInfo t) => (Object)(object)t.prefab != (Object)null).ToList(); if (source.Count == 0) { if (Plugin.PresetTemplates == null) { Plugin.PresetTemplates = PresetTemplates(); } source = Plugin.PresetTemplates; } if (source.Count == 0) { if (!Plugin.WarnedNoTemplates) { Plugin.WarnedNoTemplates = true; Plugin.Log.LogWarning((object)$"LootTopup ({reason}): level short (goal={haulGoal}, achievable={num6:0}, items={count}) but no templates to spawn from."); } return; } float avgVal = source.Average((Plugin.TemplateInfo t) => t.value); List<Plugin.TemplateInfo> list2 = source.Where((Plugin.TemplateInfo t) => t.value <= avgVal).ToList(); if (list2.Count == 0) { list2 = source; } if (Plugin.Spots.Count == 0) { if (!Plugin.WarnedNoSpots) { Plugin.WarnedNoSpots = true; Plugin.Log.LogWarning((object)$"LootTopup ({reason}): level short (goal={haulGoal}, achievable={num6:0}, items={count}) but no valuable spawn points were recorded."); } return; } bool mp = SemiFunc.IsMultiplayer(); Plugin.Busy = true; int num9 = 0; int num10 = 0; int num11 = 0; List<Vector3> list3 = new List<Vector3>(); Plugin.Log.LogInfo((object)$"LootTopup ({reason}): topping up. goal={haulGoal} achievable={num6:0} (target {num7:0}), items={count} (min {value}), spawn points={Plugin.Spots.Count}."); try { while ((num6 < num7 || count + num9 < value) && num11 < 500 && Plugin.SpawnedThisLevel + num10 < Plugin.MaxSpawnsPerLevel.Value) { num11++; List<Plugin.TemplateInfo> list4 = ((num6 < num7) ? source : list2).Where((Plugin.TemplateInfo x) => !Plugin.SpawnBlacklist.Contains(x.resourceId)).ToList(); if (list4.Count == 0) { Plugin.Log.LogWarning((object)("LootTopup (" + reason + "): all viable templates are blacklisted; stopping topup.")); break; } Plugin.TemplateInfo tmpl = list4[Random.Range(0, list4.Count)]; if ((Object)(object)tmpl.prefab == (Object)null) { continue; } if (!TryPickSpot(tmpl.volumeType, list3, list, out var pos, out var rot)) { Plugin.Log.LogWarning((object)("LootTopup (" + reason + "): no valuable spawn point left to place a copy.")); break; } list3.Add(pos); GameObject val; try { val = TrySpawn(tmpl, mp, pos, rot); } catch (Exception ex) { if (Plugin.SpawnBlacklist.Add(tmpl.resourceId)) { Plugin.Log.LogWarning((object)("LootTopup: spawn exception for '" + tmpl.resourceId + "' (" + ex.Message + "); blacklisting for this level.")); } num10++; continue; } if ((Object)(object)val == (Object)null) { if (Plugin.SpawnBlacklist.Add(tmpl.resourceId)) { Plugin.Log.LogWarning((object)("LootTopup: spawn returned null for '" + tmpl.resourceId + "'; blacklisting for this level.")); } num10++; continue; } ValuableObject component = val.GetComponent<ValuableObject>(); if (!((Object)(object)component == (Object)null)) { try { component.DollarValueSetLogic(); } catch { } num6 += component.dollarValueCurrent; num9++; num10++; } } } finally { Plugin.Busy = false; } Plugin.SpawnedThisLevel += num10; int num12 = num10 - num9; string text = ((num12 > 0) ? $" ({num12} failed/blacklisted)" : ""); Plugin.Log.LogInfo((object)$"LootTopup ({reason}): spawned {num9} valuable(s){text}; achievable now ~{num6:0} vs goal {haulGoal}, level total spawned {Plugin.SpawnedThisLevel}."); } private static bool NoLootMutatorActive() { try { string[] array = (from s in (Plugin.SkipMutatorNames.Value ?? "").Split(',') select s.Trim() into s where s.Length > 0 select s).ToArray(); if (array.Length == 0) { return false; } if (!_mutatorLookupDone) { _mutatorLookupDone = true; _mutatorManagerType = AppDomain.CurrentDomain.GetAssemblies().SelectMany(delegate(Assembly a) { try { return a.GetTypes(); } catch { return Array.Empty<Type>(); } }).FirstOrDefault((Type t) => t.Name == "MutatorManager"); } if (_mutatorManagerType == null) { return false; } object obj = (_mutatorManagerType.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public) ?? _mutatorManagerType.GetProperty("instance", BindingFlags.Static | BindingFlags.Public))?.GetValue(null); if (obj == null) { return false; } if (!(obj.GetType().GetProperty("RegisteredMutators")?.GetValue(obj) is IEnumerable enumerable)) { return false; } foreach (object item in enumerable) { object obj2 = item.GetType().GetProperty("Value")?.GetValue(item); if (obj2 == null) { continue; } PropertyInfo property = obj2.GetType().GetProperty("Active"); if (property == null) { continue; } object value = property.GetValue(obj2); if (value is bool && (bool)value) { string mname = (obj2.GetType().GetProperty("MutatorName")?.GetValue(obj2) as string) ?? ""; if (array.Any((string s) => string.Equals(s, mname, StringComparison.OrdinalIgnoreCase))) { Plugin.Log.LogInfo((object)("LootTopup: '" + mname + "' mutator active - skipping topup (intentional no-loot).")); return true; } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("LootTopup: mutator check failed (proceeding): " + ex.Message)); } return false; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }