Decompiled source of LC Lives v1.0.3

slenered.LC_Lives.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Extensions;
using CSync.Lib;
using GameNetcodeStuff;
using HarmonyLib;
using LCVR;
using LCVR.Patches.Spectating;
using LCVR.Player;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("LCVR")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("slenered.LC_Lives")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Adds lives to Lethal Company for parties less than for.")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3")]
[assembly: AssemblyProduct("slenered.LC_Lives")]
[assembly: AssemblyTitle("slenered.LC_Lives")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.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 LC_Lives
{
	public class Configs : SyncedConfig2<Configs>
	{
		[field: SyncedEntryField]
		public SyncedEntry<int> PartySize { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> GlobalLives { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> PlayerLives { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> RespawnTimeSeconds { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<bool> ReviveOnBodyCollectedBool { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<bool> PreventShipFromLeaving { get; private set; }

		public Configs(ConfigFile configFile)
			: base("slenered.LC_Lives")
		{
			PartySize = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, "General", "Party Size", 4, "The number lives that the team shares. (Each player consumes a life by landing)");
			GlobalLives = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, "General", "Global Lives", 0, "Additional lives that the team shares.");
			PlayerLives = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, "General", "Player Lives", 0, "The number lives that each player has.");
			ReviveOnBodyCollectedBool = SyncedBindingExtensions.BindSyncedEntry<bool>(configFile, "General", "Revive on body collection", true, "Force revive a player when their body is returned to the ship.");
			RespawnTimeSeconds = SyncedBindingExtensions.BindSyncedEntry<float>(configFile, "General", "Respawn Timer (Seconds)", 30f, "The amount of time before respawning a player.");
			PreventShipFromLeaving = SyncedBindingExtensions.BindSyncedEntry<bool>(configFile, "General", "Prevent Ship From Leaving", false, "Stop the ship from leaving if there are lives left.");
			ConfigManager.Register<Configs>((SyncedConfig2<Configs>)(object)this);
			PartySize.Changed += delegate(object _, SyncedSettingChangedEventArgs<int> args)
			{
				Logger.LogInfo((object)$"(NOW) PartySize: {args.OldValue} -> {args.NewValue}");
			};
			GlobalLives.Changed += delegate(object _, SyncedSettingChangedEventArgs<int> args)
			{
				Logger.LogInfo((object)$"(NOW) GlobalLives: {args.OldValue} -> {args.NewValue}");
			};
			PlayerLives.Changed += delegate(object _, SyncedSettingChangedEventArgs<int> args)
			{
				Logger.LogInfo((object)$"(NOW) PlayerLives: {args.OldValue} -> {args.NewValue}");
			};
			PreventShipFromLeaving.Changed += delegate(object _, SyncedSettingChangedEventArgs<bool> args)
			{
				Logger.LogInfo((object)$"(NOW) PreventShipFromLeaving: {args.OldValue} -> {args.NewValue}");
			};
			RespawnTimeSeconds.Changed += delegate(object _, SyncedSettingChangedEventArgs<float> args)
			{
				if (args.NewValue > 0f)
				{
					Logger.LogInfo((object)"(NOW) On Timer!");
					LC_Lives.RevivePlayerMetric.RevivePlayerSystem.AddReviveCondition(new LC_Lives.RevivePlayerMetric.ReviveOnTimer());
				}
				else
				{
					Logger.LogInfo((object)"(NOW) Off on Timer!");
					LC_Lives.RevivePlayerMetric.RevivePlayerSystem.RemoveReviveCondition(new LC_Lives.RevivePlayerMetric.ReviveOnTimer());
				}
			};
			ReviveOnBodyCollectedBool.Changed += delegate(object _, SyncedSettingChangedEventArgs<bool> args)
			{
				if (args.NewValue)
				{
					Logger.LogInfo((object)"(NOW) On Body Collect!");
					LC_Lives.RevivePlayerMetric.RevivePlayerSystem.AddReviveCondition(new LC_Lives.RevivePlayerMetric.ReviveOnBodyCollected());
				}
				else
				{
					Logger.LogInfo((object)"(NOW) Off on Body Collect!");
					LC_Lives.RevivePlayerMetric.RevivePlayerSystem.RemoveReviveCondition(new LC_Lives.RevivePlayerMetric.ReviveOnBodyCollected());
				}
			};
		}
	}
	[BepInPlugin("slenered.LC_Lives", "slenered.LC_Lives", "1.0.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency("com.sigurd.csync", "5.0.1")]
	public class LC_Lives : BaseUnityPlugin
	{
		internal class RevivePlayerMetric
		{
			internal static class RevivePlayerSystem
			{
				private static readonly List<IReviveCondition> SReviveActions = new List<IReviveCondition>();

				private static readonly Dictionary<ulong, RevivePlayerMetric> SPlayerMetrics = new Dictionary<ulong, RevivePlayerMetric>();

				public static void AddReviveCondition(IReviveCondition condition)
				{
					SReviveActions.Add(condition);
				}

				public static void RemoveReviveCondition(IReviveCondition condition)
				{
					SReviveActions.Remove(condition);
				}

				public static void ClearReviveActions()
				{
					SReviveActions.Clear();
				}

				[HarmonyPatch(typeof(StartOfRound), "ShipLeaveAutomatically")]
				[HarmonyPrefix]
				private static bool ShipLeaveAutomaticallyPatch(StartOfRound __instance)
				{
					bool flag = false;
					foreach (RevivePlayerMetric value in SPlayerMetrics.Values)
					{
						if (value.CanRevive())
						{
							flag = true;
							break;
						}
					}
					Logger.LogInfo((object)TimeOfDay.Instance.shipLeavingOnMidnight);
					if (_config.PreventShipFromLeaving.Value && flag && !TimeOfDay.Instance.shipLeavingOnMidnight)
					{
						__instance.allPlayersDead = false;
						return false;
					}
					return true;
				}

				[HarmonyPatch(typeof(RoundManager), "FinishGeneratingNewLevelClientRpc")]
				[HarmonyPrefix]
				private static void ResetMetricsOnRoundStart()
				{
					Logger.LogError((object)"Round Manager Finished Level Generation!");
					StartOfRound instance = StartOfRound.Instance;
					SPlayerMetrics.Clear();
					if (instance == null)
					{
						Logger.LogError((object)"Start of Round is null at 'FinishGeneratingNewLevelClientRpc'");
						return;
					}
					SReviveActions.ForEach(delegate(IReviveCondition x)
					{
						x.Reset();
					});
					int value = _config.PlayerLives.Value;
					PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts;
					PlayerControllerB[] array = allPlayerScripts;
					foreach (PlayerControllerB val in array)
					{
						ulong actualClientId = val.actualClientId;
						string playerUsername = val.playerUsername;
						if (actualClientId == 0L && !val.isHostPlayerObject)
						{
							break;
						}
						Logger.LogInfo((object)$"Starting Revive Tracking for: '{actualClientId}' => '{playerUsername}'");
						SPlayerMetrics.Add(val.actualClientId, new RevivePlayerMetric(val, value));
					}
					Instance.GlobalLivesLeft = _config.GlobalLives.Value + Math.Max(_config.PartySize.Value - instance.livingPlayers, 0);
					if (Object.op_Implicit((Object)(object)HUDManager.Instance))
					{
						HUDManager.Instance.DisplayTip("Lives", $"{Instance.GlobalLivesLeft} Global lives,\n{value} Personal lives.", false, false, "LC_Tip1");
					}
				}

				[HarmonyPatch(typeof(StartOfRound), "Update")]
				[HarmonyPrefix]
				private static void TryRevivePlayers(ref StartOfRound __instance)
				{
					//IL_0134: Unknown result type (might be due to invalid IL or missing references)
					if (!__instance.shipHasLanded || __instance.inShipPhase)
					{
						return;
					}
					if (SPlayerMetrics.Count <= 0 || SReviveActions.Count <= 0)
					{
						Logger.LogInfo((object)"No revive actions or players available to revive");
						return;
					}
					foreach (KeyValuePair<ulong, RevivePlayerMetric> sPlayerMetric in SPlayerMetrics)
					{
						sPlayerMetric.Deconstruct(out var key, out var value);
						ulong num = key;
						RevivePlayerMetric revivePlayerMetric = value;
						PlayerControllerB player = revivePlayerMetric.Player;
						if (!player.isPlayerDead || (player != null && player.actualClientId == 0L && !player.isHostPlayerObject))
						{
							continue;
						}
						foreach (IReviveCondition sReviveAction in SReviveActions)
						{
							if (revivePlayerMetric.CanRevive() && sReviveAction.ShouldRevivePlayer(revivePlayerMetric))
							{
								SReviveActions.ForEach(delegate(IReviveCondition x)
								{
									x.SoftReset(revivePlayerMetric);
								});
								Logger.LogInfo((object)$"Reviving Player '{num}' => '{player.playerUsername}'");
								revivePlayerMetric.Revive(sReviveAction.GetRevivePosition(revivePlayerMetric));
							}
						}
					}
				}
			}

			internal class ReviveOnBodyCollected : IReviveCondition
			{
				private readonly Dictionary<ulong, float> _mTimers = new Dictionary<ulong, float>();

				public void Reset()
				{
					_mTimers.Clear();
				}

				public void SoftReset(RevivePlayerMetric metric)
				{
					ulong actualClientId = metric.Player.actualClientId;
					_mTimers[actualClientId] = 0f;
				}

				public bool ShouldRevivePlayer(RevivePlayerMetric metric)
				{
					if (_config.ReviveOnBodyCollectedBool.Value && metric.Player.isPlayerDead)
					{
						ulong actualClientId = metric.Player.actualClientId;
						float num = 5f;
						if (!_mTimers.TryGetValue(actualClientId, out var value))
						{
							_mTimers.Add(actualClientId, 0f);
							return false;
						}
						_mTimers[actualClientId] = value + Time.deltaTime;
						value = _mTimers[actualClientId];
						if (value > num)
						{
							_mTimers[actualClientId] = 0f;
							return metric.Player.deadBody.isInShip;
						}
					}
					return false;
				}
			}

			internal class ReviveOnTimer : IReviveCondition
			{
				private readonly Dictionary<ulong, float> _mTimers = new Dictionary<ulong, float>();

				public void Reset()
				{
					_mTimers.Clear();
				}

				public void SoftReset(RevivePlayerMetric metric)
				{
					ulong actualClientId = metric.Player.actualClientId;
					_mTimers[actualClientId] = 0f;
				}

				public bool ShouldRevivePlayer(RevivePlayerMetric metric)
				{
					if (!metric.Player.isPlayerDead)
					{
						return false;
					}
					ulong actualClientId = metric.Player.actualClientId;
					float value = _config.RespawnTimeSeconds.Value;
					if (!_mTimers.TryGetValue(actualClientId, out var value2))
					{
						_mTimers.Add(actualClientId, 0f);
						return false;
					}
					_mTimers[actualClientId] = value2 + Time.deltaTime;
					value2 = _mTimers[actualClientId];
					if (value2 > value)
					{
						_mTimers[actualClientId] = 0f;
						return true;
					}
					return false;
				}
			}

			private PlayerControllerB Player { get; }

			private int LivesLeft { get; set; }

			private RevivePlayerMetric(PlayerControllerB player, int revives)
			{
				Player = player;
				LivesLeft = revives;
			}

			private bool CanRevive()
			{
				return LivesLeft + Instance.GlobalLivesLeft > 0;
			}

			private int GetPlayerIndex()
			{
				StartOfRound instance = StartOfRound.Instance;
				if (instance == null)
				{
					throw new NullReferenceException("Start of round is null");
				}
				for (int i = 0; i < instance.allPlayerScripts.Length; i++)
				{
					PlayerControllerB val = instance.allPlayerScripts[i];
					if (val.actualClientId == Player.actualClientId && (val.actualClientId != 0L || val.isHostPlayerObject))
					{
						return i;
					}
				}
				throw new ArgumentException("Unknown Player Index: " + (object)Player);
			}

			private void Revive(Vector3 revivePos)
			{
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_026c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0271: Unknown result type (might be due to invalid IL or missing references)
				if (!CanRevive())
				{
					return;
				}
				StartOfRound instance = StartOfRound.Instance;
				if (Instance.inVR)
				{
					ReviveVRPlayer();
				}
				int playerIndex = GetPlayerIndex();
				instance.livingPlayers++;
				Player.isClimbingLadder = false;
				Player.clampLooking = false;
				Player.inVehicleAnimation = false;
				Player.disableMoveInput = false;
				Player.ResetZAndXRotation();
				((Collider)Player.thisController).enabled = true;
				Player.health = 100;
				Player.hasBeenCriticallyInjured = false;
				Player.disableLookInput = false;
				Player.disableInteract = false;
				Player.isPlayerDead = false;
				Player.isPlayerControlled = true;
				Player.isInElevator = true;
				Player.isInHangarShipRoom = true;
				Player.isInsideFactory = false;
				Player.parentedToElevatorLastFrame = false;
				Player.overrideGameOverSpectatePivot = null;
				instance.SetPlayerObjectExtrapolate(false);
				Player.TeleportPlayer(revivePos, false, 0f, false, true);
				Player.setPositionOfDeadPlayer = false;
				Player.DisablePlayerModel(instance.allPlayerObjects[playerIndex], true, true);
				((Behaviour)Player.helmetLight).enabled = false;
				Player.Crouch(false);
				Player.criticallyInjured = false;
				if ((Object)(object)Player.playerBodyAnimator != (Object)null)
				{
					Player.playerBodyAnimator.SetBool(LimpAnimator, false);
				}
				Player.bleedingHeavily = false;
				Player.activatingItem = false;
				Player.twoHanded = false;
				Player.inShockingMinigame = false;
				Player.inSpecialInteractAnimation = false;
				Player.freeRotationInInteractAnimation = false;
				Player.disableSyncInAnimation = false;
				Player.inAnimationWithEnemy = null;
				Player.holdingWalkieTalkie = false;
				Player.speakingToWalkieTalkie = false;
				Player.isSinking = false;
				Player.isUnderwater = false;
				Player.sinkingValue = 0f;
				Player.statusEffectAudio.Stop();
				Player.DisableJetpackControlsLocally();
				Player.mapRadarDotAnimator.SetBool(DeadAnimator, false);
				Player.externalForceAutoFade = Vector3.zero;
				if (((NetworkBehaviour)Player).IsOwner)
				{
					HUDManager.Instance.gasHelmetAnimator.SetBool(GasEmittingAnimator, false);
					Player.hasBegunSpectating = false;
					HUDManager.Instance.RemoveSpectateUI();
					HUDManager.Instance.gameOverAnimator.SetTrigger(ReviveAnimator);
					Player.hinderedMultiplier = 1f;
					Player.isMovementHindered = 0;
					Player.sourcesCausingSinking = 0;
					Player.reverbPreset = instance.shipReverb;
					HUDManager.Instance.UpdateHealthUI(100, false);
					((Behaviour)HUDManager.Instance.audioListenerLowPass).enabled = false;
					HUDManager.Instance.HideHUD(false);
				}
				SoundManager.Instance.earsRingingTimer = 0f;
				Player.voiceMuffledByEnemy = false;
				SoundManager.Instance.playerVoicePitchTargets[playerIndex] = 1f;
				SoundManager.Instance.SetPlayerPitch(1f, playerIndex);
				if ((Object)(object)Player.currentVoiceChatIngameSettings == (Object)null)
				{
					instance.RefreshPlayerVoicePlaybackObjects();
				}
				if ((Object)(object)Player.currentVoiceChatIngameSettings != (Object)null)
				{
					if ((Object)(object)Player.currentVoiceChatIngameSettings.voiceAudio == (Object)null)
					{
						Player.currentVoiceChatIngameSettings.InitializeComponents();
					}
					if ((Object)(object)Player.currentVoiceChatIngameSettings.voiceAudio == (Object)null)
					{
						return;
					}
					((Component)Player.currentVoiceChatIngameSettings.voiceAudio).GetComponent<OccludeAudio>().overridingLowPass = false;
				}
				Player.spectatedPlayerScript = null;
				instance.SetSpectateCameraToGameOverMode(false, Player);
				instance.UpdatePlayerVoiceEffects();
				Logger.LogInfo((object)$"LivesLeft: {LivesLeft} | GlobalLivesLeft: {Instance.GlobalLivesLeft}");
				if (LivesLeft > 0)
				{
					int livesLeft = LivesLeft - 1;
					LivesLeft = livesLeft;
					if (Object.op_Implicit((Object)(object)HUDManager.Instance) && ((NetworkBehaviour)Player).IsOwner)
					{
						HUDManager.Instance.DisplayTip("Lives", $"You have {LivesLeft} live(s) left.", LivesLeft <= 1, false, "LC_Tip1");
					}
				}
				else
				{
					int globalLivesLeft = Instance.GlobalLivesLeft - 1;
					Instance.GlobalLivesLeft = globalLivesLeft;
					if (Object.op_Implicit((Object)(object)HUDManager.Instance))
					{
						HUDManager.Instance.DisplayTip("Lives", $"There are {Instance.GlobalLivesLeft} team live(s) left.", Instance.GlobalLivesLeft <= 1, false, "LC_Tip1");
					}
				}
			}

			private void ReviveVRPlayer()
			{
				SpectatorPlayerPatches.OnPlayerRevived();
			}
		}

		internal interface IReviveCondition
		{
			void Reset();

			void SoftReset(RevivePlayerMetric metric);

			bool ShouldRevivePlayer(RevivePlayerMetric metric);

			Vector3 GetRevivePosition(RevivePlayerMetric _)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				return StartOfRound.Instance.middleOfShipNode.position;
			}
		}

		public bool inVR;

		private static Configs _config = null;

		private static readonly int LimpAnimator = Animator.StringToHash("Limp");

		private static readonly int DeadAnimator = Animator.StringToHash("dead");

		private static readonly int GasEmittingAnimator = Animator.StringToHash("gasEmitting");

		private static readonly int ReviveAnimator = Animator.StringToHash("revive");

		private static LC_Lives Instance { get; set; } = null;


		private static ManualLogSource Logger { get; set; } = null;


		private static Harmony? Harmony { get; set; }

		private int GlobalLivesLeft { get; set; }

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Harmony = new Harmony("slenered.LC_Lives");
			if (Chainloader.PluginInfos.ContainsKey("io.daxcess.lcvr"))
			{
				LCVRCompatibility();
			}
			else
			{
				Logger.LogInfo((object)"LCVR was not found. Skipping...");
			}
			_config = new Configs(((BaseUnityPlugin)this).Config);
			((SyncedConfig2<Configs>)(object)_config).InitialSyncCompleted += delegate
			{
				Logger.LogInfo((object)"Initial sync complete!");
				if (_config.ReviveOnBodyCollectedBool.Value)
				{
					Logger.LogInfo((object)"On Body Collect!");
					RevivePlayerMetric.RevivePlayerSystem.AddReviveCondition(new RevivePlayerMetric.ReviveOnBodyCollected());
				}
				if (_config.RespawnTimeSeconds.Value > 0f)
				{
					Logger.LogInfo((object)"On Timer!");
					RevivePlayerMetric.RevivePlayerSystem.AddReviveCondition(new RevivePlayerMetric.ReviveOnTimer());
				}
			};
			try
			{
				Harmony.PatchAll(typeof(RevivePlayerMetric.RevivePlayerSystem));
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Failed to patch Revive System; '" + ex.Message + "'\n" + ex.StackTrace));
			}
			Logger.LogInfo((object)$"PartySize: {_config.PartySize.Value}");
			Logger.LogInfo((object)$"GlobalLives: {_config.GlobalLives.Value}");
			Logger.LogInfo((object)$"PlayerLives: {_config.PlayerLives.Value}");
			Logger.LogInfo((object)$"ReviveOnBodyCollectedBool: {_config.ReviveOnBodyCollectedBool.Value}");
			Logger.LogInfo((object)$"RespawnTimeSeconds: {_config.RespawnTimeSeconds.Value}");
			Logger.LogInfo((object)$"PreventShipFromLeaving: {_config.PreventShipFromLeaving.Value}");
			Logger.LogInfo((object)"------------------------------------------");
			Logger.LogInfo((object)"slenered.LC_Lives v1.0.3 has loaded!");
		}

		private void LCVRCompatibility()
		{
			Logger.LogInfo((object)"LCVR Found!");
			inVR = VRSession.InVR;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "slenered.LC_Lives";

		public const string PLUGIN_NAME = "slenered.LC_Lives";

		public const string PLUGIN_VERSION = "1.0.3";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}