Decompiled source of StatusCore v0.1.0

plugins/ArceDev.StatusCore.dll

Decompiled 10 hours ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
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.Logging;
using FishNet;
using FishNet.Broadcast;
using FishNet.Connection;
using FishNet.Object;
using FishNet.Serializing;
using FishNet.Transporting;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NativeStatusUI;
using UnityEngine;

[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("ArceDev.StatusCore")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("ArceDev.StatusCore")]
[assembly: AssemblyTitle("Status Core")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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")]
	[Embedded]
	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")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace StatusCore
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("ArceDev.StatusCore", "Status Core", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Player), "OnStartClient")]
		private static class PlayerStartPatch
		{
			private static void Postfix()
			{
				StatusApi.RegisterClient();
			}
		}

		[HarmonyPatch(typeof(Server), "OnStartClient")]
		private static class ServerStartPatch
		{
			private static void Postfix()
			{
				StatusApi.RegisterClient();
			}
		}

		[HarmonyPatch(typeof(Server), "OnStopClient")]
		private static class ServerStopPatch
		{
			private static void Prefix()
			{
				StatusApi.ResetSession();
			}
		}

		public const string Id = "ArceDev.StatusCore";

		internal static ManualLogSource Log { get; private set; }

		public static string Name => "Status Core";

		public static string Version => "0.1.0";

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			StatusApi.InitializeNetwork();
			StatusApi.Validate();
			Harmony.CreateAndPatchAll(typeof(Plugin).Assembly, "ArceDev.StatusCore");
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}

		private void Update()
		{
			StatusApi.UpdateServer();
		}
	}
	public enum StatusRemovalReason : byte
	{
		Expired,
		Removed,
		TargetUnavailable,
		SessionEnded
	}
	public sealed class StatusDefinition
	{
		private readonly byte[] _iconPng;

		public string Id { get; }

		public string DisplayName { get; }

		public Color Color { get; }

		public float TickInterval { get; }

		public bool RemoveOnDeath { get; }

		internal Action<StatusContext>? OnApplied { get; }

		internal Action<StatusContext>? OnTick { get; }

		internal Action<StatusContext, StatusRemovalReason>? OnRemoved { get; }

		internal byte[] IconPng => _iconPng;

		public StatusDefinition(string id, string displayName, byte[] iconPng, Color color, float tickInterval = 0f, Action<StatusContext>? onApplied = null, Action<StatusContext>? onTick = null, Action<StatusContext, StatusRemovalReason>? onRemoved = null, bool removeOnDeath = true)
		{
			//IL_0053: 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)
			Id = Required(id, "id");
			DisplayName = Required(displayName, "displayName");
			if (iconPng == null || iconPng.Length <= 0)
			{
				throw new ArgumentException("A status icon PNG is required.", "iconPng");
			}
			_iconPng = (byte[])iconPng.Clone();
			Color = color;
			if (!(tickInterval >= 0f))
			{
				throw new ArgumentOutOfRangeException("tickInterval");
			}
			TickInterval = tickInterval;
			OnApplied = onApplied;
			OnTick = onTick;
			OnRemoved = onRemoved;
			RemoveOnDeath = removeOnDeath;
		}

		private static string Required(string value, string parameter)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				throw new ArgumentException("A non-empty value is required.", parameter);
			}
			return value;
		}
	}
	public readonly record struct StatusContext(string StatusId, Player Target, Player? Source, float Duration, float Remaining);
	public readonly record struct StatusSnapshot(string StatusId, int TargetObjectId, int SourceObjectId, float Duration, float Remaining);
	internal readonly record struct StatusChangeBroadcast(string StatusId, float Duration, bool Active) : IBroadcast;
	public static class StatusApi
	{
		private readonly record struct StatusKey(int TargetObjectId, string StatusId);

		private readonly record struct LocalStatus(float Duration, float ExpiresAt);

		private sealed class ActiveStatus
		{
			internal Player Target { get; }

			internal Player? Source { get; }

			internal float Duration { get; }

			internal float ExpiresAt { get; }

			internal float NextTick { get; set; }

			internal ActiveStatus(Player target, Player? source, float duration, float expiresAt, float nextTick)
			{
				Target = target;
				Source = source;
				Duration = duration;
				ExpiresAt = expiresAt;
				NextTick = nextTick;
			}
		}

		private static readonly Dictionary<string, StatusDefinition> Definitions = new Dictionary<string, StatusDefinition>(StringComparer.Ordinal);

		private static readonly List<StatusDefinition> Ordered = new List<StatusDefinition>();

		private static readonly Dictionary<StatusKey, ActiveStatus> ServerStatuses = new Dictionary<StatusKey, ActiveStatus>();

		private static readonly Dictionary<string, LocalStatus> LocalStatuses = new Dictionary<string, LocalStatus>(StringComparer.Ordinal);

		private static readonly Action<StatusChangeBroadcast, Channel> ClientHandler = OnClientChange;

		private static bool _networkInitialized;

		private static bool _clientRegistered;

		public static IReadOnlyList<StatusDefinition> Catalog => Ordered.AsReadOnly();

		public static void Register(StatusDefinition definition)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (definition == null)
			{
				throw new ArgumentNullException("definition");
			}
			if (!Definitions.TryAdd(definition.Id, definition))
			{
				throw new InvalidOperationException("Status '" + definition.Id + "' is already registered.");
			}
			Ordered.Add(definition);
			NativeStatus.Register(definition.Id, definition.IconPng, definition.Color);
		}

		public static void Apply(Player target, string statusId, float duration, Player? source = null)
		{
			EnsureServer();
			if (!Object.op_Implicit((Object)(object)target) || ((NetworkBehaviour)target).IsDeinitializing)
			{
				throw new ArgumentNullException("target");
			}
			if (duration <= 0f)
			{
				throw new ArgumentOutOfRangeException("duration");
			}
			StatusDefinition statusDefinition = Definition(statusId);
			float time = Time.time;
			ActiveStatus activeStatus = new ActiveStatus(target, source, duration, time + duration, (statusDefinition.TickInterval > 0f) ? (time + statusDefinition.TickInterval) : 0f);
			ServerStatuses[new StatusKey(((NetworkBehaviour)target).ObjectId, statusId)] = activeStatus;
			statusDefinition.OnApplied?.Invoke(Context(statusId, activeStatus, time));
			Send(target, new StatusChangeBroadcast(statusId, duration, Active: true));
		}

		public static bool Remove(Player target, string statusId)
		{
			EnsureServer();
			if (Object.op_Implicit((Object)(object)target))
			{
				return Remove(new StatusKey(((NetworkBehaviour)target).ObjectId, statusId), StatusRemovalReason.Removed, notify: true);
			}
			return false;
		}

		public static bool IsActive(Player target, string statusId)
		{
			if (!Object.op_Implicit((Object)(object)target) || !Definitions.ContainsKey(statusId))
			{
				return false;
			}
			ActiveStatus active;
			if (InstanceFinder.IsServerStarted)
			{
				return TryGetServer(new StatusKey(((NetworkBehaviour)target).ObjectId, statusId), out active);
			}
			LocalStatus local;
			float remaining;
			if (((NetworkBehaviour)target).IsOwner)
			{
				return TryGetLocal(statusId, out local, out remaining);
			}
			return false;
		}

		public static bool TryGet(Player target, string statusId, out StatusSnapshot snapshot)
		{
			snapshot = default(StatusSnapshot);
			if (!Object.op_Implicit((Object)(object)target) || !Definitions.ContainsKey(statusId))
			{
				return false;
			}
			if (InstanceFinder.IsServerStarted && TryGetServer(new StatusKey(((NetworkBehaviour)target).ObjectId, statusId), out ActiveStatus active))
			{
				snapshot = Snapshot(statusId, active, Time.time);
				return true;
			}
			if (!((NetworkBehaviour)target).IsOwner || !TryGetLocal(statusId, out var local, out var remaining))
			{
				return false;
			}
			snapshot = new StatusSnapshot(statusId, ((NetworkBehaviour)target).ObjectId, -1, local.Duration, remaining);
			return true;
		}

		internal static void InitializeNetwork()
		{
			if (!_networkInitialized)
			{
				GenericWriter<StatusChangeBroadcast>.SetWrite((Action<Writer, StatusChangeBroadcast>)WriteChange);
				GenericReader<StatusChangeBroadcast>.SetRead((Func<Reader, StatusChangeBroadcast>)ReadChange);
				_networkInitialized = true;
			}
		}

		internal static void RegisterClient()
		{
			if (!_clientRegistered && Object.op_Implicit((Object)(object)InstanceFinder.ClientManager))
			{
				InstanceFinder.ClientManager.RegisterBroadcast<StatusChangeBroadcast>(ClientHandler);
				_clientRegistered = true;
			}
		}

		internal static void UpdateServer()
		{
			if (InstanceFinder.IsServerStarted && ServerStatuses.Count != 0)
			{
				float time = Time.time;
				StatusKey[] array = ServerStatuses.Keys.ToArray();
				foreach (StatusKey key in array)
				{
					UpdateStatus(key, time);
				}
			}
		}

		internal static void ResetSession()
		{
			if (_clientRegistered && Object.op_Implicit((Object)(object)InstanceFinder.ClientManager))
			{
				InstanceFinder.ClientManager.UnregisterBroadcast<StatusChangeBroadcast>(ClientHandler);
			}
			StatusKey[] array = ServerStatuses.Keys.ToArray();
			foreach (StatusKey key in array)
			{
				Remove(key, StatusRemovalReason.SessionEnded, notify: false);
			}
			string[] array2 = LocalStatuses.Keys.ToArray();
			foreach (string text in array2)
			{
				NativeStatus.Hide(text);
			}
			LocalStatuses.Clear();
			_clientRegistered = false;
		}

		internal static void Validate()
		{
			if (Remaining(10f, 15f, 7f) != 8f || Remaining(10f, 5f, 7f) != 0f)
			{
				throw new InvalidOperationException("Status Core duration validation failed.");
			}
		}

		private static void UpdateStatus(StatusKey key, float now)
		{
			ActiveStatus activeStatus = ServerStatuses[key];
			StatusDefinition statusDefinition = Definitions[key.StatusId];
			StatusRemovalReason? statusRemovalReason = RemovalReason(activeStatus, statusDefinition, now);
			if (statusRemovalReason.HasValue)
			{
				Remove(key, statusRemovalReason.Value, statusRemovalReason != StatusRemovalReason.TargetUnavailable);
			}
			else if (!(statusDefinition.TickInterval <= 0f) && !(now < activeStatus.NextTick))
			{
				statusDefinition.OnTick?.Invoke(Context(key.StatusId, activeStatus, now));
				activeStatus.NextTick = now + statusDefinition.TickInterval;
			}
		}

		private static StatusRemovalReason? RemovalReason(ActiveStatus active, StatusDefinition definition, float now)
		{
			if (!Object.op_Implicit((Object)(object)active.Target) || ((NetworkBehaviour)active.Target).IsDeinitializing)
			{
				return StatusRemovalReason.TargetUnavailable;
			}
			if (now >= active.ExpiresAt)
			{
				return StatusRemovalReason.Expired;
			}
			if (!definition.RemoveOnDeath || !active.Target.Dying.IsDead)
			{
				return null;
			}
			return StatusRemovalReason.TargetUnavailable;
		}

		private static bool Remove(StatusKey key, StatusRemovalReason reason, bool notify)
		{
			if (!ServerStatuses.TryGetValue(key, out ActiveStatus value))
			{
				return false;
			}
			ServerStatuses.Remove(key);
			Definitions[key.StatusId].OnRemoved?.Invoke(Context(key.StatusId, value, Time.time), reason);
			if (notify && Object.op_Implicit((Object)(object)value.Target))
			{
				Send(value.Target, new StatusChangeBroadcast(key.StatusId, 0f, Active: false));
			}
			return true;
		}

		private static bool TryGetServer(StatusKey key, out ActiveStatus active)
		{
			if (!ServerStatuses.TryGetValue(key, out active))
			{
				return false;
			}
			StatusRemovalReason? statusRemovalReason = RemovalReason(active, Definitions[key.StatusId], Time.time);
			if (!statusRemovalReason.HasValue)
			{
				return true;
			}
			Remove(key, statusRemovalReason.Value, notify: true);
			active = null;
			return false;
		}

		private static bool TryGetLocal(string statusId, out LocalStatus local, out float remaining)
		{
			if (LocalStatuses.TryGetValue(statusId, out local))
			{
				remaining = Mathf.Max(0f, local.ExpiresAt - Time.time);
				if (remaining > 0f)
				{
					return true;
				}
				LocalStatuses.Remove(statusId);
				NativeStatus.Hide(statusId);
			}
			local = default(LocalStatus);
			remaining = 0f;
			return false;
		}

		private static void OnClientChange(StatusChangeBroadcast message, Channel channel)
		{
			if (Definitions.ContainsKey(message.StatusId))
			{
				if (message.Active && message.Duration > 0f)
				{
					LocalStatuses[message.StatusId] = new LocalStatus(message.Duration, Time.time + message.Duration);
					NativeStatus.Activate(message.StatusId, message.Duration);
				}
				else
				{
					LocalStatuses.Remove(message.StatusId);
					NativeStatus.Hide(message.StatusId);
				}
			}
		}

		private static void Send(Player target, StatusChangeBroadcast message)
		{
			NetworkConnection owner = ((NetworkBehaviour)target).Owner;
			if (owner != null && owner.IsValid && Object.op_Implicit((Object)(object)InstanceFinder.ServerManager))
			{
				InstanceFinder.ServerManager.Broadcast<StatusChangeBroadcast>(owner, message, true, (Channel)0);
			}
		}

		private static StatusDefinition Definition(string id)
		{
			if (!Definitions.TryGetValue(id, out StatusDefinition value))
			{
				throw new KeyNotFoundException("Status '" + id + "' is not registered.");
			}
			return value;
		}

		private static void EnsureServer()
		{
			if (!InstanceFinder.IsServerStarted)
			{
				throw new InvalidOperationException("Statuses can only be applied by the server.");
			}
		}

		private static StatusContext Context(string id, ActiveStatus active, float now)
		{
			return new StatusContext(id, active.Target, active.Source, active.Duration, Remaining(active.Duration, active.ExpiresAt, now));
		}

		private static StatusSnapshot Snapshot(string id, ActiveStatus active, float now)
		{
			return new StatusSnapshot(id, ((NetworkBehaviour)active.Target).ObjectId, Object.op_Implicit((Object)(object)active.Source) ? ((NetworkBehaviour)active.Source).ObjectId : (-1), active.Duration, Remaining(active.Duration, active.ExpiresAt, now));
		}

		private static float Remaining(float duration, float expiresAt, float now)
		{
			if (!(duration > 0f))
			{
				return 0f;
			}
			return Mathf.Clamp(expiresAt - now, 0f, duration);
		}

		private static void WriteChange(Writer writer, StatusChangeBroadcast message)
		{
			writer.WriteString(message.StatusId);
			writer.WriteSingle(message.Duration);
			writer.WriteBoolean(message.Active);
		}

		private static StatusChangeBroadcast ReadChange(Reader reader)
		{
			return new StatusChangeBroadcast(reader.ReadStringAllocated(), reader.ReadSingle(), reader.ReadBoolean());
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ConstantExpectedAttribute : Attribute
	{
		public object? Min { get; set; }

		public object? Max { get; set; }
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal static class IsExternalInit
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class OverloadResolutionPriorityAttribute : Attribute
	{
		public int Priority { get; }

		public OverloadResolutionPriorityAttribute(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
}