Decompiled source of NebulaMultiplayerMod v0.9.3

discord_game_sdk_dotnet.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("discord_game_sdk_dotnet")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3bb1ae4284b5f16508d9789eff7fcce645bb08ea")]
[assembly: AssemblyProduct("discord_game_sdk_dotnet")]
[assembly: AssemblyTitle("discord_game_sdk_dotnet")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Discord;

public class ActivityManager
{
	public delegate void AcceptInviteHandler(Result result);

	public delegate void ActivityInviteHandler(ActivityActionType type, ref User user, ref Activity activity);

	public delegate void ActivityJoinHandler(string secret);

	public delegate void ActivityJoinRequestHandler(ref User user);

	public delegate void ActivitySpectateHandler(string secret);

	public delegate void ClearActivityHandler(Result result);

	public delegate void SendInviteHandler(Result result);

	public delegate void SendRequestReplyHandler(Result result);

	public delegate void UpdateActivityHandler(Result result);

	internal struct FFIEvents
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ActivityJoinHandler(IntPtr ptr, [MarshalAs(UnmanagedType.LPStr)] string secret);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ActivitySpectateHandler(IntPtr ptr, [MarshalAs(UnmanagedType.LPStr)] string secret);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ActivityJoinRequestHandler(IntPtr ptr, ref User user);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ActivityInviteHandler(IntPtr ptr, ActivityActionType type, ref User user, ref Activity activity);

		internal ActivityJoinHandler OnActivityJoin;

		internal ActivitySpectateHandler OnActivitySpectate;

		internal ActivityJoinRequestHandler OnActivityJoinRequest;

		internal ActivityInviteHandler OnActivityInvite;
	}

	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result RegisterCommandMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string command);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result RegisterSteamMethod(IntPtr methodsPtr, uint steamId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void UpdateActivityCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void UpdateActivityMethod(IntPtr methodsPtr, ref Activity activity, IntPtr callbackData, UpdateActivityCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ClearActivityCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ClearActivityMethod(IntPtr methodsPtr, IntPtr callbackData, ClearActivityCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SendRequestReplyCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SendRequestReplyMethod(IntPtr methodsPtr, long userId, ActivityJoinRequestReply reply, IntPtr callbackData, SendRequestReplyCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SendInviteCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SendInviteMethod(IntPtr methodsPtr, long userId, ActivityActionType type, [MarshalAs(UnmanagedType.LPStr)] string content, IntPtr callbackData, SendInviteCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void AcceptInviteCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void AcceptInviteMethod(IntPtr methodsPtr, long userId, IntPtr callbackData, AcceptInviteCallback callback);

		internal RegisterCommandMethod RegisterCommand;

		internal RegisterSteamMethod RegisterSteam;

		internal UpdateActivityMethod UpdateActivity;

		internal ClearActivityMethod ClearActivity;

		internal SendRequestReplyMethod SendRequestReply;

		internal SendInviteMethod SendInvite;

		internal AcceptInviteMethod AcceptInvite;
	}

	private readonly IntPtr MethodsPtr;

	private object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	public event ActivityJoinHandler OnActivityJoin;

	public event ActivitySpectateHandler OnActivitySpectate;

	public event ActivityJoinRequestHandler OnActivityJoinRequest;

	public event ActivityInviteHandler OnActivityInvite;

	public void RegisterCommand()
	{
		RegisterCommand(null);
	}

	internal ActivityManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events)
	{
		if (eventsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
		InitEvents(eventsPtr, ref events);
		MethodsPtr = ptr;
		if (MethodsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
	}

	private void InitEvents(IntPtr eventsPtr, ref FFIEvents events)
	{
		events.OnActivityJoin = OnActivityJoinImpl;
		events.OnActivitySpectate = OnActivitySpectateImpl;
		events.OnActivityJoinRequest = OnActivityJoinRequestImpl;
		events.OnActivityInvite = OnActivityInviteImpl;
		Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false);
	}

	public void RegisterCommand(string command)
	{
		Result result = Methods.RegisterCommand(MethodsPtr, command);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void RegisterSteam(uint steamId)
	{
		Result result = Methods.RegisterSteam(MethodsPtr, steamId);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	[MonoPInvokeCallback]
	private static void UpdateActivityCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		UpdateActivityHandler obj = (UpdateActivityHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void UpdateActivity(Activity activity, UpdateActivityHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.UpdateActivity(MethodsPtr, ref activity, GCHandle.ToIntPtr(value), UpdateActivityCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void ClearActivityCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		ClearActivityHandler obj = (ClearActivityHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void ClearActivity(ClearActivityHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.ClearActivity(MethodsPtr, GCHandle.ToIntPtr(value), ClearActivityCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void SendRequestReplyCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		SendRequestReplyHandler obj = (SendRequestReplyHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void SendRequestReply(long userId, ActivityJoinRequestReply reply, SendRequestReplyHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.SendRequestReply(MethodsPtr, userId, reply, GCHandle.ToIntPtr(value), SendRequestReplyCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void SendInviteCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		SendInviteHandler obj = (SendInviteHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void SendInvite(long userId, ActivityActionType type, string content, SendInviteHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.SendInvite(MethodsPtr, userId, type, content, GCHandle.ToIntPtr(value), SendInviteCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void AcceptInviteCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		AcceptInviteHandler obj = (AcceptInviteHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void AcceptInvite(long userId, AcceptInviteHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.AcceptInvite(MethodsPtr, userId, GCHandle.ToIntPtr(value), AcceptInviteCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void OnActivityJoinImpl(IntPtr ptr, string secret)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.ActivityManagerInstance.OnActivityJoin != null)
		{
			discord.ActivityManagerInstance.OnActivityJoin(secret);
		}
	}

	[MonoPInvokeCallback]
	private static void OnActivitySpectateImpl(IntPtr ptr, string secret)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.ActivityManagerInstance.OnActivitySpectate != null)
		{
			discord.ActivityManagerInstance.OnActivitySpectate(secret);
		}
	}

	[MonoPInvokeCallback]
	private static void OnActivityJoinRequestImpl(IntPtr ptr, ref User user)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.ActivityManagerInstance.OnActivityJoinRequest != null)
		{
			discord.ActivityManagerInstance.OnActivityJoinRequest(ref user);
		}
	}

	[MonoPInvokeCallback]
	private static void OnActivityInviteImpl(IntPtr ptr, ActivityActionType type, ref User user, ref Activity activity)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.ActivityManagerInstance.OnActivityInvite != null)
		{
			discord.ActivityManagerInstance.OnActivityInvite(type, ref user, ref activity);
		}
	}
}
internal static class Constants
{
	public const string DllName = "discord_game_sdk";
}
public enum Result
{
	Ok,
	ServiceUnavailable,
	InvalidVersion,
	LockFailed,
	InternalError,
	InvalidPayload,
	InvalidCommand,
	InvalidPermissions,
	NotFetched,
	NotFound,
	Conflict,
	InvalidSecret,
	InvalidJoinSecret,
	NoEligibleActivity,
	InvalidInvite,
	NotAuthenticated,
	InvalidAccessToken,
	ApplicationMismatch,
	InvalidDataUrl,
	InvalidBase64,
	NotFiltered,
	LobbyFull,
	InvalidLobbySecret,
	InvalidFilename,
	InvalidFileSize,
	InvalidEntitlement,
	NotInstalled,
	NotRunning,
	InsufficientBuffer,
	PurchaseCanceled,
	InvalidGuild,
	InvalidEvent,
	InvalidChannel,
	InvalidOrigin,
	RateLimited,
	OAuth2Error,
	SelectChannelTimeout,
	GetGuildTimeout,
	SelectVoiceForceRequired,
	CaptureShortcutAlreadyListening,
	UnauthorizedForAchievement,
	InvalidGiftCode,
	PurchaseError,
	TransactionAborted
}
public enum CreateFlags
{
	Default,
	NoRequireDiscord
}
public enum LogLevel
{
	Error = 1,
	Warn,
	Info,
	Debug
}
public enum UserFlag
{
	Partner = 2,
	HypeSquadEvents = 4,
	HypeSquadHouse1 = 0x40,
	HypeSquadHouse2 = 0x80,
	HypeSquadHouse3 = 0x100
}
public enum PremiumType
{
	None,
	Tier1,
	Tier2
}
public enum ImageType
{
	User
}
public enum ActivityType
{
	Playing,
	Streaming,
	Listening,
	Watching
}
public enum ActivityActionType
{
	Join = 1,
	Spectate
}
public enum ActivityJoinRequestReply
{
	No,
	Yes,
	Ignore
}
public enum Status
{
	Offline,
	Online,
	Idle,
	DoNotDisturb
}
public enum RelationshipType
{
	None,
	Friend,
	Blocked,
	PendingIncoming,
	PendingOutgoing,
	Implicit
}
public enum LobbyType
{
	Private = 1,
	Public
}
public enum LobbySearchComparison
{
	LessThanOrEqual = -2,
	LessThan,
	Equal,
	GreaterThan,
	GreaterThanOrEqual,
	NotEqual
}
public enum LobbySearchCast
{
	String = 1,
	Number
}
public enum LobbySearchDistance
{
	Local,
	Default,
	Extended,
	Global
}
public enum EntitlementType
{
	Purchase = 1,
	PremiumSubscription,
	DeveloperGift,
	TestModePurchase,
	FreePurchase,
	UserGift,
	PremiumPurchase
}
public enum SkuType
{
	Application = 1,
	DLC,
	Consumable,
	Bundle
}
public enum InputModeType
{
	VoiceActivity,
	PushToTalk
}
public struct User
{
	public long Id;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
	public string Username;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
	public string Discriminator;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string Avatar;

	public bool Bot;
}
public struct OAuth2Token
{
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string AccessToken;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
	public string Scopes;

	public long Expires;
}
public struct ImageHandle
{
	public ImageType Type;

	public long Id;

	public uint Size;

	public static ImageHandle User(long id)
	{
		return User(id, 128u);
	}

	public static ImageHandle User(long id, uint size)
	{
		ImageHandle result = default(ImageHandle);
		result.Type = ImageType.User;
		result.Id = id;
		result.Size = size;
		return result;
	}
}
public struct ImageDimensions
{
	public uint Width;

	public uint Height;
}
public struct ActivityTimestamps
{
	public long Start;

	public long End;
}
public struct ActivityAssets
{
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string LargeImage;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string LargeText;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string SmallImage;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string SmallText;
}
public struct PartySize
{
	public int CurrentSize;

	public int MaxSize;
}
public struct ActivityParty
{
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string Id;

	public PartySize Size;
}
public struct ActivitySecrets
{
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string Match;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string Join;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string Spectate;
}
public struct Activity
{
	public ActivityType Type;

	public long ApplicationId;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string Name;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string State;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string Details;

	public ActivityTimestamps Timestamps;

	public ActivityAssets Assets;

	public ActivityParty Party;

	public ActivitySecrets Secrets;

	public bool Instance;
}
public struct Presence
{
	public Status Status;

	public Activity Activity;
}
public struct Relationship
{
	public RelationshipType Type;

	public User User;

	public Presence Presence;
}
public struct Lobby
{
	public long Id;

	public LobbyType Type;

	public long OwnerId;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	public string Secret;

	public uint Capacity;

	public bool Locked;
}
public struct FileStat
{
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
	public string Filename;

	public ulong Size;

	public ulong LastModified;
}
public struct Entitlement
{
	public long Id;

	public EntitlementType Type;

	public long SkuId;
}
public struct SkuPrice
{
	public uint Amount;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
	public string Currency;
}
public struct Sku
{
	public long Id;

	public SkuType Type;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
	public string Name;

	public SkuPrice Price;
}
public struct InputMode
{
	public InputModeType Type;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
	public string Shortcut;
}
public struct UserAchievement
{
	public long UserId;

	public long AchievementId;

	public byte PercentComplete;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
	public string UnlockedAt;
}
public struct LobbyTransaction
{
	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result SetTypeMethod(IntPtr methodsPtr, LobbyType type);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result SetOwnerMethod(IntPtr methodsPtr, long ownerId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result SetCapacityMethod(IntPtr methodsPtr, uint capacity);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result SetMetadataMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key, [MarshalAs(UnmanagedType.LPStr)] string value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result DeleteMetadataMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result SetLockedMethod(IntPtr methodsPtr, bool locked);

		internal SetTypeMethod SetType;

		internal SetOwnerMethod SetOwner;

		internal SetCapacityMethod SetCapacity;

		internal SetMetadataMethod SetMetadata;

		internal DeleteMetadataMethod DeleteMetadata;

		internal SetLockedMethod SetLocked;
	}

	internal IntPtr MethodsPtr;

	internal object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	public void SetType(LobbyType type)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.SetType(MethodsPtr, type);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}

	public void SetOwner(long ownerId)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.SetOwner(MethodsPtr, ownerId);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}

	public void SetCapacity(uint capacity)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.SetCapacity(MethodsPtr, capacity);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}

	public void SetMetadata(string key, string value)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.SetMetadata(MethodsPtr, key, value);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}

	public void DeleteMetadata(string key)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.DeleteMetadata(MethodsPtr, key);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}

	public void SetLocked(bool locked)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.SetLocked(MethodsPtr, locked);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}
}
public struct LobbyMemberTransaction
{
	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result SetMetadataMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key, [MarshalAs(UnmanagedType.LPStr)] string value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result DeleteMetadataMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key);

		internal SetMetadataMethod SetMetadata;

		internal DeleteMetadataMethod DeleteMetadata;
	}

	internal IntPtr MethodsPtr;

	internal object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	public void SetMetadata(string key, string value)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.SetMetadata(MethodsPtr, key, value);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}

	public void DeleteMetadata(string key)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.DeleteMetadata(MethodsPtr, key);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}
}
public struct LobbySearchQuery
{
	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result FilterMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key, LobbySearchComparison comparison, LobbySearchCast cast, [MarshalAs(UnmanagedType.LPStr)] string value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result SortMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key, LobbySearchCast cast, [MarshalAs(UnmanagedType.LPStr)] string value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result LimitMethod(IntPtr methodsPtr, uint limit);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result DistanceMethod(IntPtr methodsPtr, LobbySearchDistance distance);

		internal FilterMethod Filter;

		internal SortMethod Sort;

		internal LimitMethod Limit;

		internal DistanceMethod Distance;
	}

	internal IntPtr MethodsPtr;

	internal object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	public void Filter(string key, LobbySearchComparison comparison, LobbySearchCast cast, string value)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.Filter(MethodsPtr, key, comparison, cast, value);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}

	public void Sort(string key, LobbySearchCast cast, string value)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.Sort(MethodsPtr, key, cast, value);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}

	public void Limit(uint limit)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.Limit(MethodsPtr, limit);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}

	public void Distance(LobbySearchDistance distance)
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Result result = Methods.Distance(MethodsPtr, distance);
			if (result != 0)
			{
				throw new ResultException(result);
			}
		}
	}
}
public class ResultException : Exception
{
	public readonly Result Result;

	public ResultException(Result result)
		: base(result.ToString())
	{
	}
}
public class Discord : IDisposable
{
	public delegate void SetLogHookHandler(LogLevel level, string message);

	internal struct FFIEvents
	{
	}

	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void DestroyHandler(IntPtr MethodsPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result RunCallbacksMethod(IntPtr methodsPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SetLogHookCallback(IntPtr ptr, LogLevel level, [MarshalAs(UnmanagedType.LPStr)] string message);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SetLogHookMethod(IntPtr methodsPtr, LogLevel minLevel, IntPtr callbackData, SetLogHookCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetApplicationManagerMethod(IntPtr discordPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetUserManagerMethod(IntPtr discordPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetImageManagerMethod(IntPtr discordPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetActivityManagerMethod(IntPtr discordPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetRelationshipManagerMethod(IntPtr discordPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetLobbyManagerMethod(IntPtr discordPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetNetworkManagerMethod(IntPtr discordPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetOverlayManagerMethod(IntPtr discordPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetStorageManagerMethod(IntPtr discordPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetStoreManagerMethod(IntPtr discordPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetVoiceManagerMethod(IntPtr discordPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr GetAchievementManagerMethod(IntPtr discordPtr);

		internal DestroyHandler Destroy;

		internal RunCallbacksMethod RunCallbacks;

		internal SetLogHookMethod SetLogHook;

		internal GetApplicationManagerMethod GetApplicationManager;

		internal GetUserManagerMethod GetUserManager;

		internal GetImageManagerMethod GetImageManager;

		internal GetActivityManagerMethod GetActivityManager;

		internal GetRelationshipManagerMethod GetRelationshipManager;

		internal GetLobbyManagerMethod GetLobbyManager;

		internal GetNetworkManagerMethod GetNetworkManager;

		internal GetOverlayManagerMethod GetOverlayManager;

		internal GetStorageManagerMethod GetStorageManager;

		internal GetStoreManagerMethod GetStoreManager;

		internal GetVoiceManagerMethod GetVoiceManager;

		internal GetAchievementManagerMethod GetAchievementManager;
	}

	internal struct FFICreateParams
	{
		internal long ClientId;

		internal ulong Flags;

		internal IntPtr Events;

		internal IntPtr EventData;

		internal IntPtr ApplicationEvents;

		internal uint ApplicationVersion;

		internal IntPtr UserEvents;

		internal uint UserVersion;

		internal IntPtr ImageEvents;

		internal uint ImageVersion;

		internal IntPtr ActivityEvents;

		internal uint ActivityVersion;

		internal IntPtr RelationshipEvents;

		internal uint RelationshipVersion;

		internal IntPtr LobbyEvents;

		internal uint LobbyVersion;

		internal IntPtr NetworkEvents;

		internal uint NetworkVersion;

		internal IntPtr OverlayEvents;

		internal uint OverlayVersion;

		internal IntPtr StorageEvents;

		internal uint StorageVersion;

		internal IntPtr StoreEvents;

		internal uint StoreVersion;

		internal IntPtr VoiceEvents;

		internal uint VoiceVersion;

		internal IntPtr AchievementEvents;

		internal uint AchievementVersion;
	}

	private AchievementManager.FFIEvents AchievementEvents;

	private readonly IntPtr AchievementEventsPtr;

	internal AchievementManager AchievementManagerInstance;

	private ActivityManager.FFIEvents ActivityEvents;

	private readonly IntPtr ActivityEventsPtr;

	internal ActivityManager ActivityManagerInstance;

	private ApplicationManager.FFIEvents ApplicationEvents;

	private readonly IntPtr ApplicationEventsPtr;

	internal ApplicationManager ApplicationManagerInstance;

	private readonly FFIEvents Events;

	private readonly IntPtr EventsPtr;

	private ImageManager.FFIEvents ImageEvents;

	private readonly IntPtr ImageEventsPtr;

	internal ImageManager ImageManagerInstance;

	private LobbyManager.FFIEvents LobbyEvents;

	private readonly IntPtr LobbyEventsPtr;

	internal LobbyManager LobbyManagerInstance;

	private readonly IntPtr MethodsPtr;

	private object MethodsStructure;

	private NetworkManager.FFIEvents NetworkEvents;

	private readonly IntPtr NetworkEventsPtr;

	internal NetworkManager NetworkManagerInstance;

	private OverlayManager.FFIEvents OverlayEvents;

	private readonly IntPtr OverlayEventsPtr;

	internal OverlayManager OverlayManagerInstance;

	private RelationshipManager.FFIEvents RelationshipEvents;

	private readonly IntPtr RelationshipEventsPtr;

	internal RelationshipManager RelationshipManagerInstance;

	private GCHandle SelfHandle;

	private GCHandle? setLogHook;

	private StorageManager.FFIEvents StorageEvents;

	private readonly IntPtr StorageEventsPtr;

	internal StorageManager StorageManagerInstance;

	private StoreManager.FFIEvents StoreEvents;

	private readonly IntPtr StoreEventsPtr;

	internal StoreManager StoreManagerInstance;

	private UserManager.FFIEvents UserEvents;

	private readonly IntPtr UserEventsPtr;

	internal UserManager UserManagerInstance;

	private VoiceManager.FFIEvents VoiceEvents;

	private readonly IntPtr VoiceEventsPtr;

	internal VoiceManager VoiceManagerInstance;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	public Discord(long clientId, ulong flags)
	{
		FFICreateParams createParams = default(FFICreateParams);
		createParams.ClientId = clientId;
		createParams.Flags = flags;
		Events = default(FFIEvents);
		EventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Events));
		createParams.Events = EventsPtr;
		SelfHandle = GCHandle.Alloc(this);
		createParams.EventData = GCHandle.ToIntPtr(SelfHandle);
		ApplicationEvents = default(ApplicationManager.FFIEvents);
		ApplicationEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ApplicationEvents));
		createParams.ApplicationEvents = ApplicationEventsPtr;
		createParams.ApplicationVersion = 1u;
		UserEvents = default(UserManager.FFIEvents);
		UserEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(UserEvents));
		createParams.UserEvents = UserEventsPtr;
		createParams.UserVersion = 1u;
		ImageEvents = default(ImageManager.FFIEvents);
		ImageEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ImageEvents));
		createParams.ImageEvents = ImageEventsPtr;
		createParams.ImageVersion = 1u;
		ActivityEvents = default(ActivityManager.FFIEvents);
		ActivityEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ActivityEvents));
		createParams.ActivityEvents = ActivityEventsPtr;
		createParams.ActivityVersion = 1u;
		RelationshipEvents = default(RelationshipManager.FFIEvents);
		RelationshipEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(RelationshipEvents));
		createParams.RelationshipEvents = RelationshipEventsPtr;
		createParams.RelationshipVersion = 1u;
		LobbyEvents = default(LobbyManager.FFIEvents);
		LobbyEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(LobbyEvents));
		createParams.LobbyEvents = LobbyEventsPtr;
		createParams.LobbyVersion = 1u;
		NetworkEvents = default(NetworkManager.FFIEvents);
		NetworkEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(NetworkEvents));
		createParams.NetworkEvents = NetworkEventsPtr;
		createParams.NetworkVersion = 1u;
		OverlayEvents = default(OverlayManager.FFIEvents);
		OverlayEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(OverlayEvents));
		createParams.OverlayEvents = OverlayEventsPtr;
		createParams.OverlayVersion = 1u;
		StorageEvents = default(StorageManager.FFIEvents);
		StorageEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(StorageEvents));
		createParams.StorageEvents = StorageEventsPtr;
		createParams.StorageVersion = 1u;
		StoreEvents = default(StoreManager.FFIEvents);
		StoreEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(StoreEvents));
		createParams.StoreEvents = StoreEventsPtr;
		createParams.StoreVersion = 1u;
		VoiceEvents = default(VoiceManager.FFIEvents);
		VoiceEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(VoiceEvents));
		createParams.VoiceEvents = VoiceEventsPtr;
		createParams.VoiceVersion = 1u;
		AchievementEvents = default(AchievementManager.FFIEvents);
		AchievementEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(AchievementEvents));
		createParams.AchievementEvents = AchievementEventsPtr;
		createParams.AchievementVersion = 1u;
		InitEvents(EventsPtr, ref Events);
		Result result = DiscordCreate(2u, ref createParams, out MethodsPtr);
		if (result != 0)
		{
			Dispose();
			throw new ResultException(result);
		}
	}

	public void Dispose()
	{
		if (MethodsPtr != IntPtr.Zero)
		{
			Methods.Destroy(MethodsPtr);
		}
		SelfHandle.Free();
		Marshal.FreeHGlobal(EventsPtr);
		Marshal.FreeHGlobal(ApplicationEventsPtr);
		Marshal.FreeHGlobal(UserEventsPtr);
		Marshal.FreeHGlobal(ImageEventsPtr);
		Marshal.FreeHGlobal(ActivityEventsPtr);
		Marshal.FreeHGlobal(RelationshipEventsPtr);
		Marshal.FreeHGlobal(LobbyEventsPtr);
		Marshal.FreeHGlobal(NetworkEventsPtr);
		Marshal.FreeHGlobal(OverlayEventsPtr);
		Marshal.FreeHGlobal(StorageEventsPtr);
		Marshal.FreeHGlobal(StoreEventsPtr);
		Marshal.FreeHGlobal(VoiceEventsPtr);
		Marshal.FreeHGlobal(AchievementEventsPtr);
		if (setLogHook.HasValue)
		{
			setLogHook.Value.Free();
		}
	}

	[DllImport("discord_game_sdk", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
	private static extern Result DiscordCreate(uint version, ref FFICreateParams createParams, out IntPtr manager);

	private void InitEvents(IntPtr eventsPtr, ref FFIEvents events)
	{
		Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false);
	}

	public void RunCallbacks()
	{
		Result result = Methods.RunCallbacks(MethodsPtr);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	[MonoPInvokeCallback]
	private static void SetLogHookCallbackImpl(IntPtr ptr, LogLevel level, string message)
	{
		((SetLogHookHandler)GCHandle.FromIntPtr(ptr).Target)(level, message);
	}

	public void SetLogHook(LogLevel minLevel, SetLogHookHandler callback)
	{
		if (setLogHook.HasValue)
		{
			setLogHook.Value.Free();
		}
		setLogHook = GCHandle.Alloc(callback);
		Methods.SetLogHook(MethodsPtr, minLevel, GCHandle.ToIntPtr(setLogHook.Value), SetLogHookCallbackImpl);
	}

	public ApplicationManager GetApplicationManager()
	{
		if (ApplicationManagerInstance == null)
		{
			ApplicationManagerInstance = new ApplicationManager(Methods.GetApplicationManager(MethodsPtr), ApplicationEventsPtr, ref ApplicationEvents);
		}
		return ApplicationManagerInstance;
	}

	public UserManager GetUserManager()
	{
		if (UserManagerInstance == null)
		{
			UserManagerInstance = new UserManager(Methods.GetUserManager(MethodsPtr), UserEventsPtr, ref UserEvents);
		}
		return UserManagerInstance;
	}

	public ImageManager GetImageManager()
	{
		if (ImageManagerInstance == null)
		{
			ImageManagerInstance = new ImageManager(Methods.GetImageManager(MethodsPtr), ImageEventsPtr, ref ImageEvents);
		}
		return ImageManagerInstance;
	}

	public ActivityManager GetActivityManager()
	{
		if (ActivityManagerInstance == null)
		{
			ActivityManagerInstance = new ActivityManager(Methods.GetActivityManager(MethodsPtr), ActivityEventsPtr, ref ActivityEvents);
		}
		return ActivityManagerInstance;
	}

	public RelationshipManager GetRelationshipManager()
	{
		if (RelationshipManagerInstance == null)
		{
			RelationshipManagerInstance = new RelationshipManager(Methods.GetRelationshipManager(MethodsPtr), RelationshipEventsPtr, ref RelationshipEvents);
		}
		return RelationshipManagerInstance;
	}

	public LobbyManager GetLobbyManager()
	{
		if (LobbyManagerInstance == null)
		{
			LobbyManagerInstance = new LobbyManager(Methods.GetLobbyManager(MethodsPtr), LobbyEventsPtr, ref LobbyEvents);
		}
		return LobbyManagerInstance;
	}

	public NetworkManager GetNetworkManager()
	{
		if (NetworkManagerInstance == null)
		{
			NetworkManagerInstance = new NetworkManager(Methods.GetNetworkManager(MethodsPtr), NetworkEventsPtr, ref NetworkEvents);
		}
		return NetworkManagerInstance;
	}

	public OverlayManager GetOverlayManager()
	{
		if (OverlayManagerInstance == null)
		{
			OverlayManagerInstance = new OverlayManager(Methods.GetOverlayManager(MethodsPtr), OverlayEventsPtr, ref OverlayEvents);
		}
		return OverlayManagerInstance;
	}

	public StorageManager GetStorageManager()
	{
		if (StorageManagerInstance == null)
		{
			StorageManagerInstance = new StorageManager(Methods.GetStorageManager(MethodsPtr), StorageEventsPtr, ref StorageEvents);
		}
		return StorageManagerInstance;
	}

	public StoreManager GetStoreManager()
	{
		if (StoreManagerInstance == null)
		{
			StoreManagerInstance = new StoreManager(Methods.GetStoreManager(MethodsPtr), StoreEventsPtr, ref StoreEvents);
		}
		return StoreManagerInstance;
	}

	public VoiceManager GetVoiceManager()
	{
		if (VoiceManagerInstance == null)
		{
			VoiceManagerInstance = new VoiceManager(Methods.GetVoiceManager(MethodsPtr), VoiceEventsPtr, ref VoiceEvents);
		}
		return VoiceManagerInstance;
	}

	public AchievementManager GetAchievementManager()
	{
		if (AchievementManagerInstance == null)
		{
			AchievementManagerInstance = new AchievementManager(Methods.GetAchievementManager(MethodsPtr), AchievementEventsPtr, ref AchievementEvents);
		}
		return AchievementManagerInstance;
	}
}
internal class MonoPInvokeCallbackAttribute : Attribute
{
}
public class ApplicationManager
{
	public delegate void GetOAuth2TokenHandler(Result result, ref OAuth2Token oauth2Token);

	public delegate void GetTicketHandler(Result result, ref string data);

	public delegate void ValidateOrExitHandler(Result result);

	internal struct FFIEvents
	{
	}

	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ValidateOrExitCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ValidateOrExitMethod(IntPtr methodsPtr, IntPtr callbackData, ValidateOrExitCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void GetCurrentLocaleMethod(IntPtr methodsPtr, StringBuilder locale);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void GetCurrentBranchMethod(IntPtr methodsPtr, StringBuilder branch);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void GetOAuth2TokenCallback(IntPtr ptr, Result result, ref OAuth2Token oauth2Token);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void GetOAuth2TokenMethod(IntPtr methodsPtr, IntPtr callbackData, GetOAuth2TokenCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void GetTicketCallback(IntPtr ptr, Result result, [MarshalAs(UnmanagedType.LPStr)] ref string data);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void GetTicketMethod(IntPtr methodsPtr, IntPtr callbackData, GetTicketCallback callback);

		internal ValidateOrExitMethod ValidateOrExit;

		internal GetCurrentLocaleMethod GetCurrentLocale;

		internal GetCurrentBranchMethod GetCurrentBranch;

		internal GetOAuth2TokenMethod GetOAuth2Token;

		internal GetTicketMethod GetTicket;
	}

	private readonly IntPtr MethodsPtr;

	private object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	internal ApplicationManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events)
	{
		if (eventsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
		InitEvents(eventsPtr, ref events);
		MethodsPtr = ptr;
		if (MethodsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
	}

	private void InitEvents(IntPtr eventsPtr, ref FFIEvents events)
	{
		Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false);
	}

	[MonoPInvokeCallback]
	private static void ValidateOrExitCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		ValidateOrExitHandler obj = (ValidateOrExitHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void ValidateOrExit(ValidateOrExitHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.ValidateOrExit(MethodsPtr, GCHandle.ToIntPtr(value), ValidateOrExitCallbackImpl);
	}

	public string GetCurrentLocale()
	{
		StringBuilder stringBuilder = new StringBuilder(128);
		Methods.GetCurrentLocale(MethodsPtr, stringBuilder);
		return stringBuilder.ToString();
	}

	public string GetCurrentBranch()
	{
		StringBuilder stringBuilder = new StringBuilder(4096);
		Methods.GetCurrentBranch(MethodsPtr, stringBuilder);
		return stringBuilder.ToString();
	}

	[MonoPInvokeCallback]
	private static void GetOAuth2TokenCallbackImpl(IntPtr ptr, Result result, ref OAuth2Token oauth2Token)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		GetOAuth2TokenHandler obj = (GetOAuth2TokenHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result, ref oauth2Token);
	}

	public void GetOAuth2Token(GetOAuth2TokenHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.GetOAuth2Token(MethodsPtr, GCHandle.ToIntPtr(value), GetOAuth2TokenCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void GetTicketCallbackImpl(IntPtr ptr, Result result, ref string data)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		GetTicketHandler obj = (GetTicketHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result, ref data);
	}

	public void GetTicket(GetTicketHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.GetTicket(MethodsPtr, GCHandle.ToIntPtr(value), GetTicketCallbackImpl);
	}
}
public class UserManager
{
	public delegate void CurrentUserUpdateHandler();

	public delegate void GetUserHandler(Result result, ref User user);

	internal struct FFIEvents
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void CurrentUserUpdateHandler(IntPtr ptr);

		internal CurrentUserUpdateHandler OnCurrentUserUpdate;
	}

	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetCurrentUserMethod(IntPtr methodsPtr, ref User currentUser);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void GetUserCallback(IntPtr ptr, Result result, ref User user);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void GetUserMethod(IntPtr methodsPtr, long userId, IntPtr callbackData, GetUserCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetCurrentUserPremiumTypeMethod(IntPtr methodsPtr, ref PremiumType premiumType);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result CurrentUserHasFlagMethod(IntPtr methodsPtr, UserFlag flag, ref bool hasFlag);

		internal GetCurrentUserMethod GetCurrentUser;

		internal GetUserMethod GetUser;

		internal GetCurrentUserPremiumTypeMethod GetCurrentUserPremiumType;

		internal CurrentUserHasFlagMethod CurrentUserHasFlag;
	}

	private readonly IntPtr MethodsPtr;

	private object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	public event CurrentUserUpdateHandler OnCurrentUserUpdate;

	internal UserManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events)
	{
		if (eventsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
		InitEvents(eventsPtr, ref events);
		MethodsPtr = ptr;
		if (MethodsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
	}

	private void InitEvents(IntPtr eventsPtr, ref FFIEvents events)
	{
		events.OnCurrentUserUpdate = OnCurrentUserUpdateImpl;
		Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false);
	}

	public User GetCurrentUser()
	{
		User currentUser = default(User);
		Result result = Methods.GetCurrentUser(MethodsPtr, ref currentUser);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return currentUser;
	}

	[MonoPInvokeCallback]
	private static void GetUserCallbackImpl(IntPtr ptr, Result result, ref User user)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		GetUserHandler obj = (GetUserHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result, ref user);
	}

	public void GetUser(long userId, GetUserHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.GetUser(MethodsPtr, userId, GCHandle.ToIntPtr(value), GetUserCallbackImpl);
	}

	public PremiumType GetCurrentUserPremiumType()
	{
		PremiumType premiumType = PremiumType.None;
		Result result = Methods.GetCurrentUserPremiumType(MethodsPtr, ref premiumType);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return premiumType;
	}

	public bool CurrentUserHasFlag(UserFlag flag)
	{
		bool hasFlag = false;
		Result result = Methods.CurrentUserHasFlag(MethodsPtr, flag, ref hasFlag);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return hasFlag;
	}

	[MonoPInvokeCallback]
	private static void OnCurrentUserUpdateImpl(IntPtr ptr)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.UserManagerInstance.OnCurrentUserUpdate != null)
		{
			discord.UserManagerInstance.OnCurrentUserUpdate();
		}
	}
}
public class ImageManager
{
	public delegate void FetchHandler(Result result, ImageHandle handleResult);

	internal struct FFIEvents
	{
	}

	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void FetchCallback(IntPtr ptr, Result result, ImageHandle handleResult);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void FetchMethod(IntPtr methodsPtr, ImageHandle handle, bool refresh, IntPtr callbackData, FetchCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetDimensionsMethod(IntPtr methodsPtr, ImageHandle handle, ref ImageDimensions dimensions);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetDataMethod(IntPtr methodsPtr, ImageHandle handle, byte[] data, int dataLen);

		internal FetchMethod Fetch;

		internal GetDimensionsMethod GetDimensions;

		internal GetDataMethod GetData;
	}

	private readonly IntPtr MethodsPtr;

	private object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	internal ImageManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events)
	{
		if (eventsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
		InitEvents(eventsPtr, ref events);
		MethodsPtr = ptr;
		if (MethodsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
	}

	private void InitEvents(IntPtr eventsPtr, ref FFIEvents events)
	{
		Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false);
	}

	[MonoPInvokeCallback]
	private static void FetchCallbackImpl(IntPtr ptr, Result result, ImageHandle handleResult)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		FetchHandler obj = (FetchHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result, handleResult);
	}

	public void Fetch(ImageHandle handle, bool refresh, FetchHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.Fetch(MethodsPtr, handle, refresh, GCHandle.ToIntPtr(value), FetchCallbackImpl);
	}

	public ImageDimensions GetDimensions(ImageHandle handle)
	{
		ImageDimensions dimensions = default(ImageDimensions);
		Result result = Methods.GetDimensions(MethodsPtr, handle, ref dimensions);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return dimensions;
	}

	public void GetData(ImageHandle handle, byte[] data)
	{
		Result result = Methods.GetData(MethodsPtr, handle, data, data.Length);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void Fetch(ImageHandle handle, FetchHandler callback)
	{
		Fetch(handle, refresh: false, callback);
	}

	public byte[] GetData(ImageHandle handle)
	{
		ImageDimensions dimensions = GetDimensions(handle);
		byte[] array = new byte[dimensions.Width * dimensions.Height * 4];
		GetData(handle, array);
		return array;
	}
}
public class RelationshipManager
{
	public delegate bool FilterHandler(ref Relationship relationship);

	public delegate void RefreshHandler();

	public delegate void RelationshipUpdateHandler(ref Relationship relationship);

	internal struct FFIEvents
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void RefreshHandler(IntPtr ptr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void RelationshipUpdateHandler(IntPtr ptr, ref Relationship relationship);

		internal RefreshHandler OnRefresh;

		internal RelationshipUpdateHandler OnRelationshipUpdate;
	}

	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate bool FilterCallback(IntPtr ptr, ref Relationship relationship);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void FilterMethod(IntPtr methodsPtr, IntPtr callbackData, FilterCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result CountMethod(IntPtr methodsPtr, ref int count);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetMethod(IntPtr methodsPtr, long userId, ref Relationship relationship);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetAtMethod(IntPtr methodsPtr, uint index, ref Relationship relationship);

		internal FilterMethod Filter;

		internal CountMethod Count;

		internal GetMethod Get;

		internal GetAtMethod GetAt;
	}

	private readonly IntPtr MethodsPtr;

	private object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	public event RefreshHandler OnRefresh;

	public event RelationshipUpdateHandler OnRelationshipUpdate;

	internal RelationshipManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events)
	{
		if (eventsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
		InitEvents(eventsPtr, ref events);
		MethodsPtr = ptr;
		if (MethodsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
	}

	private void InitEvents(IntPtr eventsPtr, ref FFIEvents events)
	{
		events.OnRefresh = OnRefreshImpl;
		events.OnRelationshipUpdate = OnRelationshipUpdateImpl;
		Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false);
	}

	[MonoPInvokeCallback]
	private static bool FilterCallbackImpl(IntPtr ptr, ref Relationship relationship)
	{
		return ((FilterHandler)GCHandle.FromIntPtr(ptr).Target)(ref relationship);
	}

	public void Filter(FilterHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.Filter(MethodsPtr, GCHandle.ToIntPtr(value), FilterCallbackImpl);
		value.Free();
	}

	public int Count()
	{
		int count = 0;
		Result result = Methods.Count(MethodsPtr, ref count);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return count;
	}

	public Relationship Get(long userId)
	{
		Relationship relationship = default(Relationship);
		Result result = Methods.Get(MethodsPtr, userId, ref relationship);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return relationship;
	}

	public Relationship GetAt(uint index)
	{
		Relationship relationship = default(Relationship);
		Result result = Methods.GetAt(MethodsPtr, index, ref relationship);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return relationship;
	}

	[MonoPInvokeCallback]
	private static void OnRefreshImpl(IntPtr ptr)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.RelationshipManagerInstance.OnRefresh != null)
		{
			discord.RelationshipManagerInstance.OnRefresh();
		}
	}

	[MonoPInvokeCallback]
	private static void OnRelationshipUpdateImpl(IntPtr ptr, ref Relationship relationship)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.RelationshipManagerInstance.OnRelationshipUpdate != null)
		{
			discord.RelationshipManagerInstance.OnRelationshipUpdate(ref relationship);
		}
	}
}
public class LobbyManager
{
	public delegate void ConnectLobbyHandler(Result result, ref Lobby lobby);

	public delegate void ConnectLobbyWithActivitySecretHandler(Result result, ref Lobby lobby);

	public delegate void ConnectVoiceHandler(Result result);

	public delegate void CreateLobbyHandler(Result result, ref Lobby lobby);

	public delegate void DeleteLobbyHandler(Result result);

	public delegate void DisconnectLobbyHandler(Result result);

	public delegate void DisconnectVoiceHandler(Result result);

	public delegate void LobbyDeleteHandler(long lobbyId, uint reason);

	public delegate void LobbyMessageHandler(long lobbyId, long userId, byte[] data);

	public delegate void LobbyUpdateHandler(long lobbyId);

	public delegate void MemberConnectHandler(long lobbyId, long userId);

	public delegate void MemberDisconnectHandler(long lobbyId, long userId);

	public delegate void MemberUpdateHandler(long lobbyId, long userId);

	public delegate void NetworkMessageHandler(long lobbyId, long userId, byte channelId, byte[] data);

	public delegate void SearchHandler(Result result);

	public delegate void SendLobbyMessageHandler(Result result);

	public delegate void SpeakingHandler(long lobbyId, long userId, bool speaking);

	public delegate void UpdateLobbyHandler(Result result);

	public delegate void UpdateMemberHandler(Result result);

	internal struct FFIEvents
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void LobbyUpdateHandler(IntPtr ptr, long lobbyId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void LobbyDeleteHandler(IntPtr ptr, long lobbyId, uint reason);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void MemberConnectHandler(IntPtr ptr, long lobbyId, long userId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void MemberUpdateHandler(IntPtr ptr, long lobbyId, long userId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void MemberDisconnectHandler(IntPtr ptr, long lobbyId, long userId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void LobbyMessageHandler(IntPtr ptr, long lobbyId, long userId, IntPtr dataPtr, int dataLen);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SpeakingHandler(IntPtr ptr, long lobbyId, long userId, bool speaking);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void NetworkMessageHandler(IntPtr ptr, long lobbyId, long userId, byte channelId, IntPtr dataPtr, int dataLen);

		internal LobbyUpdateHandler OnLobbyUpdate;

		internal LobbyDeleteHandler OnLobbyDelete;

		internal MemberConnectHandler OnMemberConnect;

		internal MemberUpdateHandler OnMemberUpdate;

		internal MemberDisconnectHandler OnMemberDisconnect;

		internal LobbyMessageHandler OnLobbyMessage;

		internal SpeakingHandler OnSpeaking;

		internal NetworkMessageHandler OnNetworkMessage;
	}

	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetLobbyCreateTransactionMethod(IntPtr methodsPtr, ref IntPtr transaction);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetLobbyUpdateTransactionMethod(IntPtr methodsPtr, long lobbyId, ref IntPtr transaction);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetMemberUpdateTransactionMethod(IntPtr methodsPtr, long lobbyId, long userId, ref IntPtr transaction);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void CreateLobbyCallback(IntPtr ptr, Result result, ref Lobby lobby);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void CreateLobbyMethod(IntPtr methodsPtr, IntPtr transaction, IntPtr callbackData, CreateLobbyCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void UpdateLobbyCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void UpdateLobbyMethod(IntPtr methodsPtr, long lobbyId, IntPtr transaction, IntPtr callbackData, UpdateLobbyCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void DeleteLobbyCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void DeleteLobbyMethod(IntPtr methodsPtr, long lobbyId, IntPtr callbackData, DeleteLobbyCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ConnectLobbyCallback(IntPtr ptr, Result result, ref Lobby lobby);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ConnectLobbyMethod(IntPtr methodsPtr, long lobbyId, [MarshalAs(UnmanagedType.LPStr)] string secret, IntPtr callbackData, ConnectLobbyCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ConnectLobbyWithActivitySecretCallback(IntPtr ptr, Result result, ref Lobby lobby);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ConnectLobbyWithActivitySecretMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string activitySecret, IntPtr callbackData, ConnectLobbyWithActivitySecretCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void DisconnectLobbyCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void DisconnectLobbyMethod(IntPtr methodsPtr, long lobbyId, IntPtr callbackData, DisconnectLobbyCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetLobbyMethod(IntPtr methodsPtr, long lobbyId, ref Lobby lobby);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetLobbyActivitySecretMethod(IntPtr methodsPtr, long lobbyId, StringBuilder secret);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetLobbyMetadataValueMethod(IntPtr methodsPtr, long lobbyId, [MarshalAs(UnmanagedType.LPStr)] string key, StringBuilder value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetLobbyMetadataKeyMethod(IntPtr methodsPtr, long lobbyId, int index, StringBuilder key);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result LobbyMetadataCountMethod(IntPtr methodsPtr, long lobbyId, ref int count);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result MemberCountMethod(IntPtr methodsPtr, long lobbyId, ref int count);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetMemberUserIdMethod(IntPtr methodsPtr, long lobbyId, int index, ref long userId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetMemberUserMethod(IntPtr methodsPtr, long lobbyId, long userId, ref User user);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetMemberMetadataValueMethod(IntPtr methodsPtr, long lobbyId, long userId, [MarshalAs(UnmanagedType.LPStr)] string key, StringBuilder value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetMemberMetadataKeyMethod(IntPtr methodsPtr, long lobbyId, long userId, int index, StringBuilder key);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result MemberMetadataCountMethod(IntPtr methodsPtr, long lobbyId, long userId, ref int count);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void UpdateMemberCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void UpdateMemberMethod(IntPtr methodsPtr, long lobbyId, long userId, IntPtr transaction, IntPtr callbackData, UpdateMemberCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SendLobbyMessageCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SendLobbyMessageMethod(IntPtr methodsPtr, long lobbyId, byte[] data, int dataLen, IntPtr callbackData, SendLobbyMessageCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetSearchQueryMethod(IntPtr methodsPtr, ref IntPtr query);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SearchCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SearchMethod(IntPtr methodsPtr, IntPtr query, IntPtr callbackData, SearchCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void LobbyCountMethod(IntPtr methodsPtr, ref int count);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetLobbyIdMethod(IntPtr methodsPtr, int index, ref long lobbyId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ConnectVoiceCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ConnectVoiceMethod(IntPtr methodsPtr, long lobbyId, IntPtr callbackData, ConnectVoiceCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void DisconnectVoiceCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void DisconnectVoiceMethod(IntPtr methodsPtr, long lobbyId, IntPtr callbackData, DisconnectVoiceCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result ConnectNetworkMethod(IntPtr methodsPtr, long lobbyId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result DisconnectNetworkMethod(IntPtr methodsPtr, long lobbyId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result FlushNetworkMethod(IntPtr methodsPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result OpenNetworkChannelMethod(IntPtr methodsPtr, long lobbyId, byte channelId, bool reliable);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result SendNetworkMessageMethod(IntPtr methodsPtr, long lobbyId, long userId, byte channelId, byte[] data, int dataLen);

		internal GetLobbyCreateTransactionMethod GetLobbyCreateTransaction;

		internal GetLobbyUpdateTransactionMethod GetLobbyUpdateTransaction;

		internal GetMemberUpdateTransactionMethod GetMemberUpdateTransaction;

		internal CreateLobbyMethod CreateLobby;

		internal UpdateLobbyMethod UpdateLobby;

		internal DeleteLobbyMethod DeleteLobby;

		internal ConnectLobbyMethod ConnectLobby;

		internal ConnectLobbyWithActivitySecretMethod ConnectLobbyWithActivitySecret;

		internal DisconnectLobbyMethod DisconnectLobby;

		internal GetLobbyMethod GetLobby;

		internal GetLobbyActivitySecretMethod GetLobbyActivitySecret;

		internal GetLobbyMetadataValueMethod GetLobbyMetadataValue;

		internal GetLobbyMetadataKeyMethod GetLobbyMetadataKey;

		internal LobbyMetadataCountMethod LobbyMetadataCount;

		internal MemberCountMethod MemberCount;

		internal GetMemberUserIdMethod GetMemberUserId;

		internal GetMemberUserMethod GetMemberUser;

		internal GetMemberMetadataValueMethod GetMemberMetadataValue;

		internal GetMemberMetadataKeyMethod GetMemberMetadataKey;

		internal MemberMetadataCountMethod MemberMetadataCount;

		internal UpdateMemberMethod UpdateMember;

		internal SendLobbyMessageMethod SendLobbyMessage;

		internal GetSearchQueryMethod GetSearchQuery;

		internal SearchMethod Search;

		internal LobbyCountMethod LobbyCount;

		internal GetLobbyIdMethod GetLobbyId;

		internal ConnectVoiceMethod ConnectVoice;

		internal DisconnectVoiceMethod DisconnectVoice;

		internal ConnectNetworkMethod ConnectNetwork;

		internal DisconnectNetworkMethod DisconnectNetwork;

		internal FlushNetworkMethod FlushNetwork;

		internal OpenNetworkChannelMethod OpenNetworkChannel;

		internal SendNetworkMessageMethod SendNetworkMessage;
	}

	private readonly IntPtr MethodsPtr;

	private object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	public event LobbyUpdateHandler OnLobbyUpdate;

	public event LobbyDeleteHandler OnLobbyDelete;

	public event MemberConnectHandler OnMemberConnect;

	public event MemberUpdateHandler OnMemberUpdate;

	public event MemberDisconnectHandler OnMemberDisconnect;

	public event LobbyMessageHandler OnLobbyMessage;

	public event SpeakingHandler OnSpeaking;

	public event NetworkMessageHandler OnNetworkMessage;

	internal LobbyManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events)
	{
		if (eventsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
		InitEvents(eventsPtr, ref events);
		MethodsPtr = ptr;
		if (MethodsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
	}

	private void InitEvents(IntPtr eventsPtr, ref FFIEvents events)
	{
		events.OnLobbyUpdate = OnLobbyUpdateImpl;
		events.OnLobbyDelete = OnLobbyDeleteImpl;
		events.OnMemberConnect = OnMemberConnectImpl;
		events.OnMemberUpdate = OnMemberUpdateImpl;
		events.OnMemberDisconnect = OnMemberDisconnectImpl;
		events.OnLobbyMessage = OnLobbyMessageImpl;
		events.OnSpeaking = OnSpeakingImpl;
		events.OnNetworkMessage = OnNetworkMessageImpl;
		Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false);
	}

	public LobbyTransaction GetLobbyCreateTransaction()
	{
		LobbyTransaction result = default(LobbyTransaction);
		Result result2 = Methods.GetLobbyCreateTransaction(MethodsPtr, ref result.MethodsPtr);
		if (result2 != 0)
		{
			throw new ResultException(result2);
		}
		return result;
	}

	public LobbyTransaction GetLobbyUpdateTransaction(long lobbyId)
	{
		LobbyTransaction result = default(LobbyTransaction);
		Result result2 = Methods.GetLobbyUpdateTransaction(MethodsPtr, lobbyId, ref result.MethodsPtr);
		if (result2 != 0)
		{
			throw new ResultException(result2);
		}
		return result;
	}

	public LobbyMemberTransaction GetMemberUpdateTransaction(long lobbyId, long userId)
	{
		LobbyMemberTransaction result = default(LobbyMemberTransaction);
		Result result2 = Methods.GetMemberUpdateTransaction(MethodsPtr, lobbyId, userId, ref result.MethodsPtr);
		if (result2 != 0)
		{
			throw new ResultException(result2);
		}
		return result;
	}

	[MonoPInvokeCallback]
	private static void CreateLobbyCallbackImpl(IntPtr ptr, Result result, ref Lobby lobby)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		CreateLobbyHandler obj = (CreateLobbyHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result, ref lobby);
	}

	public void CreateLobby(LobbyTransaction transaction, CreateLobbyHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.CreateLobby(MethodsPtr, transaction.MethodsPtr, GCHandle.ToIntPtr(value), CreateLobbyCallbackImpl);
		transaction.MethodsPtr = IntPtr.Zero;
	}

	[MonoPInvokeCallback]
	private static void UpdateLobbyCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		UpdateLobbyHandler obj = (UpdateLobbyHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void UpdateLobby(long lobbyId, LobbyTransaction transaction, UpdateLobbyHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.UpdateLobby(MethodsPtr, lobbyId, transaction.MethodsPtr, GCHandle.ToIntPtr(value), UpdateLobbyCallbackImpl);
		transaction.MethodsPtr = IntPtr.Zero;
	}

	[MonoPInvokeCallback]
	private static void DeleteLobbyCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		DeleteLobbyHandler obj = (DeleteLobbyHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void DeleteLobby(long lobbyId, DeleteLobbyHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.DeleteLobby(MethodsPtr, lobbyId, GCHandle.ToIntPtr(value), DeleteLobbyCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void ConnectLobbyCallbackImpl(IntPtr ptr, Result result, ref Lobby lobby)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		ConnectLobbyHandler obj = (ConnectLobbyHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result, ref lobby);
	}

	public void ConnectLobby(long lobbyId, string secret, ConnectLobbyHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.ConnectLobby(MethodsPtr, lobbyId, secret, GCHandle.ToIntPtr(value), ConnectLobbyCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void ConnectLobbyWithActivitySecretCallbackImpl(IntPtr ptr, Result result, ref Lobby lobby)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		ConnectLobbyWithActivitySecretHandler obj = (ConnectLobbyWithActivitySecretHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result, ref lobby);
	}

	public void ConnectLobbyWithActivitySecret(string activitySecret, ConnectLobbyWithActivitySecretHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.ConnectLobbyWithActivitySecret(MethodsPtr, activitySecret, GCHandle.ToIntPtr(value), ConnectLobbyWithActivitySecretCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void DisconnectLobbyCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		DisconnectLobbyHandler obj = (DisconnectLobbyHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void DisconnectLobby(long lobbyId, DisconnectLobbyHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.DisconnectLobby(MethodsPtr, lobbyId, GCHandle.ToIntPtr(value), DisconnectLobbyCallbackImpl);
	}

	public Lobby GetLobby(long lobbyId)
	{
		Lobby lobby = default(Lobby);
		Result result = Methods.GetLobby(MethodsPtr, lobbyId, ref lobby);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return lobby;
	}

	public string GetLobbyActivitySecret(long lobbyId)
	{
		StringBuilder stringBuilder = new StringBuilder(128);
		Result result = Methods.GetLobbyActivitySecret(MethodsPtr, lobbyId, stringBuilder);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return stringBuilder.ToString();
	}

	public string GetLobbyMetadataValue(long lobbyId, string key)
	{
		StringBuilder stringBuilder = new StringBuilder(4096);
		Result result = Methods.GetLobbyMetadataValue(MethodsPtr, lobbyId, key, stringBuilder);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return stringBuilder.ToString();
	}

	public string GetLobbyMetadataKey(long lobbyId, int index)
	{
		StringBuilder stringBuilder = new StringBuilder(256);
		Result result = Methods.GetLobbyMetadataKey(MethodsPtr, lobbyId, index, stringBuilder);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return stringBuilder.ToString();
	}

	public int LobbyMetadataCount(long lobbyId)
	{
		int count = 0;
		Result result = Methods.LobbyMetadataCount(MethodsPtr, lobbyId, ref count);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return count;
	}

	public int MemberCount(long lobbyId)
	{
		int count = 0;
		Result result = Methods.MemberCount(MethodsPtr, lobbyId, ref count);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return count;
	}

	public long GetMemberUserId(long lobbyId, int index)
	{
		long userId = 0L;
		Result result = Methods.GetMemberUserId(MethodsPtr, lobbyId, index, ref userId);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return userId;
	}

	public User GetMemberUser(long lobbyId, long userId)
	{
		User user = default(User);
		Result result = Methods.GetMemberUser(MethodsPtr, lobbyId, userId, ref user);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return user;
	}

	public string GetMemberMetadataValue(long lobbyId, long userId, string key)
	{
		StringBuilder stringBuilder = new StringBuilder(4096);
		Result result = Methods.GetMemberMetadataValue(MethodsPtr, lobbyId, userId, key, stringBuilder);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return stringBuilder.ToString();
	}

	public string GetMemberMetadataKey(long lobbyId, long userId, int index)
	{
		StringBuilder stringBuilder = new StringBuilder(256);
		Result result = Methods.GetMemberMetadataKey(MethodsPtr, lobbyId, userId, index, stringBuilder);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return stringBuilder.ToString();
	}

	public int MemberMetadataCount(long lobbyId, long userId)
	{
		int count = 0;
		Result result = Methods.MemberMetadataCount(MethodsPtr, lobbyId, userId, ref count);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return count;
	}

	[MonoPInvokeCallback]
	private static void UpdateMemberCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		UpdateMemberHandler obj = (UpdateMemberHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void UpdateMember(long lobbyId, long userId, LobbyMemberTransaction transaction, UpdateMemberHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.UpdateMember(MethodsPtr, lobbyId, userId, transaction.MethodsPtr, GCHandle.ToIntPtr(value), UpdateMemberCallbackImpl);
		transaction.MethodsPtr = IntPtr.Zero;
	}

	[MonoPInvokeCallback]
	private static void SendLobbyMessageCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		SendLobbyMessageHandler obj = (SendLobbyMessageHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void SendLobbyMessage(long lobbyId, byte[] data, SendLobbyMessageHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.SendLobbyMessage(MethodsPtr, lobbyId, data, data.Length, GCHandle.ToIntPtr(value), SendLobbyMessageCallbackImpl);
	}

	public LobbySearchQuery GetSearchQuery()
	{
		LobbySearchQuery result = default(LobbySearchQuery);
		Result result2 = Methods.GetSearchQuery(MethodsPtr, ref result.MethodsPtr);
		if (result2 != 0)
		{
			throw new ResultException(result2);
		}
		return result;
	}

	[MonoPInvokeCallback]
	private static void SearchCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		SearchHandler obj = (SearchHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void Search(LobbySearchQuery query, SearchHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.Search(MethodsPtr, query.MethodsPtr, GCHandle.ToIntPtr(value), SearchCallbackImpl);
		query.MethodsPtr = IntPtr.Zero;
	}

	public int LobbyCount()
	{
		int count = 0;
		Methods.LobbyCount(MethodsPtr, ref count);
		return count;
	}

	public long GetLobbyId(int index)
	{
		long lobbyId = 0L;
		Result result = Methods.GetLobbyId(MethodsPtr, index, ref lobbyId);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return lobbyId;
	}

	[MonoPInvokeCallback]
	private static void ConnectVoiceCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		ConnectVoiceHandler obj = (ConnectVoiceHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void ConnectVoice(long lobbyId, ConnectVoiceHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.ConnectVoice(MethodsPtr, lobbyId, GCHandle.ToIntPtr(value), ConnectVoiceCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void DisconnectVoiceCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		DisconnectVoiceHandler obj = (DisconnectVoiceHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void DisconnectVoice(long lobbyId, DisconnectVoiceHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.DisconnectVoice(MethodsPtr, lobbyId, GCHandle.ToIntPtr(value), DisconnectVoiceCallbackImpl);
	}

	public void ConnectNetwork(long lobbyId)
	{
		Result result = Methods.ConnectNetwork(MethodsPtr, lobbyId);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void DisconnectNetwork(long lobbyId)
	{
		Result result = Methods.DisconnectNetwork(MethodsPtr, lobbyId);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void FlushNetwork()
	{
		Result result = Methods.FlushNetwork(MethodsPtr);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void OpenNetworkChannel(long lobbyId, byte channelId, bool reliable)
	{
		Result result = Methods.OpenNetworkChannel(MethodsPtr, lobbyId, channelId, reliable);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void SendNetworkMessage(long lobbyId, long userId, byte channelId, byte[] data)
	{
		Result result = Methods.SendNetworkMessage(MethodsPtr, lobbyId, userId, channelId, data, data.Length);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	[MonoPInvokeCallback]
	private static void OnLobbyUpdateImpl(IntPtr ptr, long lobbyId)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.LobbyManagerInstance.OnLobbyUpdate != null)
		{
			discord.LobbyManagerInstance.OnLobbyUpdate(lobbyId);
		}
	}

	[MonoPInvokeCallback]
	private static void OnLobbyDeleteImpl(IntPtr ptr, long lobbyId, uint reason)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.LobbyManagerInstance.OnLobbyDelete != null)
		{
			discord.LobbyManagerInstance.OnLobbyDelete(lobbyId, reason);
		}
	}

	[MonoPInvokeCallback]
	private static void OnMemberConnectImpl(IntPtr ptr, long lobbyId, long userId)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.LobbyManagerInstance.OnMemberConnect != null)
		{
			discord.LobbyManagerInstance.OnMemberConnect(lobbyId, userId);
		}
	}

	[MonoPInvokeCallback]
	private static void OnMemberUpdateImpl(IntPtr ptr, long lobbyId, long userId)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.LobbyManagerInstance.OnMemberUpdate != null)
		{
			discord.LobbyManagerInstance.OnMemberUpdate(lobbyId, userId);
		}
	}

	[MonoPInvokeCallback]
	private static void OnMemberDisconnectImpl(IntPtr ptr, long lobbyId, long userId)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.LobbyManagerInstance.OnMemberDisconnect != null)
		{
			discord.LobbyManagerInstance.OnMemberDisconnect(lobbyId, userId);
		}
	}

	[MonoPInvokeCallback]
	private static void OnLobbyMessageImpl(IntPtr ptr, long lobbyId, long userId, IntPtr dataPtr, int dataLen)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.LobbyManagerInstance.OnLobbyMessage != null)
		{
			byte[] array = new byte[dataLen];
			Marshal.Copy(dataPtr, array, 0, dataLen);
			discord.LobbyManagerInstance.OnLobbyMessage(lobbyId, userId, array);
		}
	}

	[MonoPInvokeCallback]
	private static void OnSpeakingImpl(IntPtr ptr, long lobbyId, long userId, bool speaking)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.LobbyManagerInstance.OnSpeaking != null)
		{
			discord.LobbyManagerInstance.OnSpeaking(lobbyId, userId, speaking);
		}
	}

	[MonoPInvokeCallback]
	private static void OnNetworkMessageImpl(IntPtr ptr, long lobbyId, long userId, byte channelId, IntPtr dataPtr, int dataLen)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.LobbyManagerInstance.OnNetworkMessage != null)
		{
			byte[] array = new byte[dataLen];
			Marshal.Copy(dataPtr, array, 0, dataLen);
			discord.LobbyManagerInstance.OnNetworkMessage(lobbyId, userId, channelId, array);
		}
	}

	public IEnumerable<User> GetMemberUsers(long lobbyID)
	{
		int num = MemberCount(lobbyID);
		List<User> list = new List<User>();
		for (int i = 0; i < num; i++)
		{
			list.Add(GetMemberUser(lobbyID, GetMemberUserId(lobbyID, i)));
		}
		return list;
	}

	public void SendLobbyMessage(long lobbyID, string data, SendLobbyMessageHandler handler)
	{
		SendLobbyMessage(lobbyID, Encoding.UTF8.GetBytes(data), handler);
	}
}
public class NetworkManager
{
	public delegate void MessageHandler(ulong peerId, byte channelId, byte[] data);

	public delegate void RouteUpdateHandler(string routeData);

	internal struct FFIEvents
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void MessageHandler(IntPtr ptr, ulong peerId, byte channelId, IntPtr dataPtr, int dataLen);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void RouteUpdateHandler(IntPtr ptr, [MarshalAs(UnmanagedType.LPStr)] string routeData);

		internal MessageHandler OnMessage;

		internal RouteUpdateHandler OnRouteUpdate;
	}

	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void GetPeerIdMethod(IntPtr methodsPtr, ref ulong peerId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result FlushMethod(IntPtr methodsPtr);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result OpenPeerMethod(IntPtr methodsPtr, ulong peerId, [MarshalAs(UnmanagedType.LPStr)] string routeData);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result UpdatePeerMethod(IntPtr methodsPtr, ulong peerId, [MarshalAs(UnmanagedType.LPStr)] string routeData);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result ClosePeerMethod(IntPtr methodsPtr, ulong peerId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result OpenChannelMethod(IntPtr methodsPtr, ulong peerId, byte channelId, bool reliable);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result CloseChannelMethod(IntPtr methodsPtr, ulong peerId, byte channelId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result SendMessageMethod(IntPtr methodsPtr, ulong peerId, byte channelId, byte[] data, int dataLen);

		internal GetPeerIdMethod GetPeerId;

		internal FlushMethod Flush;

		internal OpenPeerMethod OpenPeer;

		internal UpdatePeerMethod UpdatePeer;

		internal ClosePeerMethod ClosePeer;

		internal OpenChannelMethod OpenChannel;

		internal CloseChannelMethod CloseChannel;

		internal SendMessageMethod SendMessage;
	}

	private readonly IntPtr MethodsPtr;

	private object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	public event MessageHandler OnMessage;

	public event RouteUpdateHandler OnRouteUpdate;

	internal NetworkManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events)
	{
		if (eventsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
		InitEvents(eventsPtr, ref events);
		MethodsPtr = ptr;
		if (MethodsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
	}

	private void InitEvents(IntPtr eventsPtr, ref FFIEvents events)
	{
		events.OnMessage = OnMessageImpl;
		events.OnRouteUpdate = OnRouteUpdateImpl;
		Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false);
	}

	public ulong GetPeerId()
	{
		ulong peerId = 0uL;
		Methods.GetPeerId(MethodsPtr, ref peerId);
		return peerId;
	}

	public void Flush()
	{
		Result result = Methods.Flush(MethodsPtr);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void OpenPeer(ulong peerId, string routeData)
	{
		Result result = Methods.OpenPeer(MethodsPtr, peerId, routeData);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void UpdatePeer(ulong peerId, string routeData)
	{
		Result result = Methods.UpdatePeer(MethodsPtr, peerId, routeData);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void ClosePeer(ulong peerId)
	{
		Result result = Methods.ClosePeer(MethodsPtr, peerId);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void OpenChannel(ulong peerId, byte channelId, bool reliable)
	{
		Result result = Methods.OpenChannel(MethodsPtr, peerId, channelId, reliable);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void CloseChannel(ulong peerId, byte channelId)
	{
		Result result = Methods.CloseChannel(MethodsPtr, peerId, channelId);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public void SendMessage(ulong peerId, byte channelId, byte[] data)
	{
		Result result = Methods.SendMessage(MethodsPtr, peerId, channelId, data, data.Length);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	[MonoPInvokeCallback]
	private static void OnMessageImpl(IntPtr ptr, ulong peerId, byte channelId, IntPtr dataPtr, int dataLen)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.NetworkManagerInstance.OnMessage != null)
		{
			byte[] array = new byte[dataLen];
			Marshal.Copy(dataPtr, array, 0, dataLen);
			discord.NetworkManagerInstance.OnMessage(peerId, channelId, array);
		}
	}

	[MonoPInvokeCallback]
	private static void OnRouteUpdateImpl(IntPtr ptr, string routeData)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.NetworkManagerInstance.OnRouteUpdate != null)
		{
			discord.NetworkManagerInstance.OnRouteUpdate(routeData);
		}
	}
}
public class OverlayManager
{
	public delegate void OpenActivityInviteHandler(Result result);

	public delegate void OpenGuildInviteHandler(Result result);

	public delegate void OpenVoiceSettingsHandler(Result result);

	public delegate void SetLockedHandler(Result result);

	public delegate void ToggleHandler(bool locked);

	internal struct FFIEvents
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ToggleHandler(IntPtr ptr, bool locked);

		internal ToggleHandler OnToggle;
	}

	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void IsEnabledMethod(IntPtr methodsPtr, ref bool enabled);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void IsLockedMethod(IntPtr methodsPtr, ref bool locked);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SetLockedCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void SetLockedMethod(IntPtr methodsPtr, bool locked, IntPtr callbackData, SetLockedCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void OpenActivityInviteCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void OpenActivityInviteMethod(IntPtr methodsPtr, ActivityActionType type, IntPtr callbackData, OpenActivityInviteCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void OpenGuildInviteCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void OpenGuildInviteMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string code, IntPtr callbackData, OpenGuildInviteCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void OpenVoiceSettingsCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void OpenVoiceSettingsMethod(IntPtr methodsPtr, IntPtr callbackData, OpenVoiceSettingsCallback callback);

		internal IsEnabledMethod IsEnabled;

		internal IsLockedMethod IsLocked;

		internal SetLockedMethod SetLocked;

		internal OpenActivityInviteMethod OpenActivityInvite;

		internal OpenGuildInviteMethod OpenGuildInvite;

		internal OpenVoiceSettingsMethod OpenVoiceSettings;
	}

	private readonly IntPtr MethodsPtr;

	private object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	public event ToggleHandler OnToggle;

	internal OverlayManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events)
	{
		if (eventsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
		InitEvents(eventsPtr, ref events);
		MethodsPtr = ptr;
		if (MethodsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
	}

	private void InitEvents(IntPtr eventsPtr, ref FFIEvents events)
	{
		events.OnToggle = OnToggleImpl;
		Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false);
	}

	public bool IsEnabled()
	{
		bool enabled = false;
		Methods.IsEnabled(MethodsPtr, ref enabled);
		return enabled;
	}

	public bool IsLocked()
	{
		bool locked = false;
		Methods.IsLocked(MethodsPtr, ref locked);
		return locked;
	}

	[MonoPInvokeCallback]
	private static void SetLockedCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		SetLockedHandler obj = (SetLockedHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void SetLocked(bool locked, SetLockedHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.SetLocked(MethodsPtr, locked, GCHandle.ToIntPtr(value), SetLockedCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void OpenActivityInviteCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		OpenActivityInviteHandler obj = (OpenActivityInviteHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void OpenActivityInvite(ActivityActionType type, OpenActivityInviteHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.OpenActivityInvite(MethodsPtr, type, GCHandle.ToIntPtr(value), OpenActivityInviteCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void OpenGuildInviteCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		OpenGuildInviteHandler obj = (OpenGuildInviteHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void OpenGuildInvite(string code, OpenGuildInviteHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.OpenGuildInvite(MethodsPtr, code, GCHandle.ToIntPtr(value), OpenGuildInviteCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void OpenVoiceSettingsCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		OpenVoiceSettingsHandler obj = (OpenVoiceSettingsHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void OpenVoiceSettings(OpenVoiceSettingsHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.OpenVoiceSettings(MethodsPtr, GCHandle.ToIntPtr(value), OpenVoiceSettingsCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void OnToggleImpl(IntPtr ptr, bool locked)
	{
		Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target;
		if (discord.OverlayManagerInstance.OnToggle != null)
		{
			discord.OverlayManagerInstance.OnToggle(locked);
		}
	}
}
public class StorageManager
{
	public delegate void ReadAsyncHandler(Result result, byte[] data);

	public delegate void ReadAsyncPartialHandler(Result result, byte[] data);

	public delegate void WriteAsyncHandler(Result result);

	internal struct FFIEvents
	{
	}

	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result ReadMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, byte[] data, int dataLen, ref uint read);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ReadAsyncCallback(IntPtr ptr, Result result, IntPtr dataPtr, int dataLen);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ReadAsyncMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, IntPtr callbackData, ReadAsyncCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ReadAsyncPartialCallback(IntPtr ptr, Result result, IntPtr dataPtr, int dataLen);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ReadAsyncPartialMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, ulong offset, ulong length, IntPtr callbackData, ReadAsyncPartialCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result WriteMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, byte[] data, int dataLen);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void WriteAsyncCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void WriteAsyncMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, byte[] data, int dataLen, IntPtr callbackData, WriteAsyncCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result DeleteMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result ExistsMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, ref bool exists);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void CountMethod(IntPtr methodsPtr, ref int count);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result StatMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, ref FileStat stat);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result StatAtMethod(IntPtr methodsPtr, int index, ref FileStat stat);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetPathMethod(IntPtr methodsPtr, StringBuilder path);

		internal ReadMethod Read;

		internal ReadAsyncMethod ReadAsync;

		internal ReadAsyncPartialMethod ReadAsyncPartial;

		internal WriteMethod Write;

		internal WriteAsyncMethod WriteAsync;

		internal DeleteMethod Delete;

		internal ExistsMethod Exists;

		internal CountMethod Count;

		internal StatMethod Stat;

		internal StatAtMethod StatAt;

		internal GetPathMethod GetPath;
	}

	private readonly IntPtr MethodsPtr;

	private object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	internal StorageManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events)
	{
		if (eventsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
		InitEvents(eventsPtr, ref events);
		MethodsPtr = ptr;
		if (MethodsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
	}

	private void InitEvents(IntPtr eventsPtr, ref FFIEvents events)
	{
		Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false);
	}

	public uint Read(string name, byte[] data)
	{
		uint read = 0u;
		Result result = Methods.Read(MethodsPtr, name, data, data.Length, ref read);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return read;
	}

	[MonoPInvokeCallback]
	private static void ReadAsyncCallbackImpl(IntPtr ptr, Result result, IntPtr dataPtr, int dataLen)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		ReadAsyncHandler obj = (ReadAsyncHandler)gCHandle.Target;
		gCHandle.Free();
		byte[] array = new byte[dataLen];
		Marshal.Copy(dataPtr, array, 0, dataLen);
		obj(result, array);
	}

	public void ReadAsync(string name, ReadAsyncHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.ReadAsync(MethodsPtr, name, GCHandle.ToIntPtr(value), ReadAsyncCallbackImpl);
	}

	[MonoPInvokeCallback]
	private static void ReadAsyncPartialCallbackImpl(IntPtr ptr, Result result, IntPtr dataPtr, int dataLen)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		ReadAsyncPartialHandler obj = (ReadAsyncPartialHandler)gCHandle.Target;
		gCHandle.Free();
		byte[] array = new byte[dataLen];
		Marshal.Copy(dataPtr, array, 0, dataLen);
		obj(result, array);
	}

	public void ReadAsyncPartial(string name, ulong offset, ulong length, ReadAsyncPartialHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.ReadAsyncPartial(MethodsPtr, name, offset, length, GCHandle.ToIntPtr(value), ReadAsyncPartialCallbackImpl);
	}

	public void Write(string name, byte[] data)
	{
		Result result = Methods.Write(MethodsPtr, name, data, data.Length);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	[MonoPInvokeCallback]
	private static void WriteAsyncCallbackImpl(IntPtr ptr, Result result)
	{
		GCHandle gCHandle = GCHandle.FromIntPtr(ptr);
		WriteAsyncHandler obj = (WriteAsyncHandler)gCHandle.Target;
		gCHandle.Free();
		obj(result);
	}

	public void WriteAsync(string name, byte[] data, WriteAsyncHandler callback)
	{
		GCHandle value = GCHandle.Alloc(callback);
		Methods.WriteAsync(MethodsPtr, name, data, data.Length, GCHandle.ToIntPtr(value), WriteAsyncCallbackImpl);
	}

	public void Delete(string name)
	{
		Result result = Methods.Delete(MethodsPtr, name);
		if (result != 0)
		{
			throw new ResultException(result);
		}
	}

	public bool Exists(string name)
	{
		bool exists = false;
		Result result = Methods.Exists(MethodsPtr, name, ref exists);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return exists;
	}

	public int Count()
	{
		int count = 0;
		Methods.Count(MethodsPtr, ref count);
		return count;
	}

	public FileStat Stat(string name)
	{
		FileStat stat = default(FileStat);
		Result result = Methods.Stat(MethodsPtr, name, ref stat);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return stat;
	}

	public FileStat StatAt(int index)
	{
		FileStat stat = default(FileStat);
		Result result = Methods.StatAt(MethodsPtr, index, ref stat);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return stat;
	}

	public string GetPath()
	{
		StringBuilder stringBuilder = new StringBuilder(4096);
		Result result = Methods.GetPath(MethodsPtr, stringBuilder);
		if (result != 0)
		{
			throw new ResultException(result);
		}
		return stringBuilder.ToString();
	}

	public IEnumerable<FileStat> Files()
	{
		int num = Count();
		List<FileStat> list = new List<FileStat>();
		for (int i = 0; i < num; i++)
		{
			list.Add(StatAt(i));
		}
		return list;
	}
}
public class StoreManager
{
	public delegate void EntitlementCreateHandler(ref Entitlement entitlement);

	public delegate void EntitlementDeleteHandler(ref Entitlement entitlement);

	public delegate void FetchEntitlementsHandler(Result result);

	public delegate void FetchSkusHandler(Result result);

	public delegate void StartPurchaseHandler(Result result);

	internal struct FFIEvents
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void EntitlementCreateHandler(IntPtr ptr, ref Entitlement entitlement);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void EntitlementDeleteHandler(IntPtr ptr, ref Entitlement entitlement);

		internal EntitlementCreateHandler OnEntitlementCreate;

		internal EntitlementDeleteHandler OnEntitlementDelete;
	}

	internal struct FFIMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void FetchSkusCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void FetchSkusMethod(IntPtr methodsPtr, IntPtr callbackData, FetchSkusCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void CountSkusMethod(IntPtr methodsPtr, ref int count);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetSkuMethod(IntPtr methodsPtr, long skuId, ref Sku sku);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetSkuAtMethod(IntPtr methodsPtr, int index, ref Sku sku);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void FetchEntitlementsCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void FetchEntitlementsMethod(IntPtr methodsPtr, IntPtr callbackData, FetchEntitlementsCallback callback);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void CountEntitlementsMethod(IntPtr methodsPtr, ref int count);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetEntitlementMethod(IntPtr methodsPtr, long entitlementId, ref Entitlement entitlement);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result GetEntitlementAtMethod(IntPtr methodsPtr, int index, ref Entitlement entitlement);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate Result HasSkuEntitlementMethod(IntPtr methodsPtr, long skuId, ref bool hasEntitlement);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void StartPurchaseCallback(IntPtr ptr, Result result);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void StartPurchaseMethod(IntPtr methodsPtr, long skuId, IntPtr callbackData, StartPurchaseCallback callback);

		internal FetchSkusMethod FetchSkus;

		internal CountSkusMethod CountSkus;

		internal GetSkuMethod GetSku;

		internal GetSkuAtMethod GetSkuAt;

		internal FetchEntitlementsMethod FetchEntitlements;

		internal CountEntitlementsMethod CountEntitlements;

		internal GetEntitlementMethod GetEntitlement;

		internal GetEntitlementAtMethod GetEntitlementAt;

		internal HasSkuEntitlementMethod HasSkuEntitlement;

		internal StartPurchaseMethod StartPurchase;
	}

	private readonly IntPtr MethodsPtr;

	private object MethodsStructure;

	private FFIMethods Methods
	{
		get
		{
			if (MethodsStructure == null)
			{
				MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods));
			}
			return (FFIMethods)MethodsStructure;
		}
	}

	public event EntitlementCreateHandler OnEntitlementCreate;

	public event EntitlementDeleteHandler OnEntitlementDelete;

	internal StoreManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events)
	{
		if (eventsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
		InitEvents(eventsPtr, ref events);
		MethodsPtr = ptr;
		if (MethodsPtr == IntPtr.Zero)
		{
			throw new ResultException(Result.InternalError);
		}
	}

	private void InitEvents(IntPtr eventsPtr, ref FFIEvents events)
	{
		events.OnEntitlementCreate = OnEntitlementCreateImpl;
		events.OnEntitlementDelete = OnEntitlementDeleteImpl;
		Marshal.Structur

K4os.Compression.LZ4.dll

Decompiled 2 weeks ago
using System;
using System.Buffers;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using K4os.Compression.LZ4.Engine;
using K4os.Compression.LZ4.Internal;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("Milosz Krajewski")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Milosz Krajewski")]
[assembly: AssemblyDescription("Port of LZ4 compression algorithm for .NET")]
[assembly: AssemblyFileVersion("1.3.8.0")]
[assembly: AssemblyInformationalVersion("1.3.8")]
[assembly: AssemblyProduct("K4os.Compression.LZ4")]
[assembly: AssemblyTitle("K4os.Compression.LZ4")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MiloszKrajewski/K4os.Compression.LZ4")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.8.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[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;
		}
	}
}
namespace System
{
	internal static class Extensions
	{
		internal static T Required<T>([NotNull] this T? value, [CallerArgumentExpression("value")] string name = null)
		{
			if (value != null)
			{
				return value;
			}
			return ThrowArgumentNullException<T>(name);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[Conditional("DEBUG")]
		public static void AssertTrue(this bool value, [CallerArgumentExpression("value")] string? name = null)
		{
			if (!value)
			{
				ThrowAssertionFailed(name);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		[DoesNotReturn]
		private static void ThrowAssertionFailed(string? name)
		{
			throw new ArgumentException((name ?? "<unknown>") + " assertion failed");
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		[DoesNotReturn]
		private static T ThrowArgumentNullException<T>(string name)
		{
			throw new ArgumentNullException(name);
		}

		internal static void Validate<T>(this T[]? buffer, int offset, int length, bool allowNullIfEmpty = false)
		{
			if (!allowNullIfEmpty || buffer != null || offset != 0 || length != 0)
			{
				if (buffer == null)
				{
					throw new ArgumentNullException("buffer", "cannot be null");
				}
				if (offset < 0 || length < 0 || offset + length > buffer.Length)
				{
					throw new ArgumentException($"invalid offset/length combination: {offset}/{length}");
				}
			}
		}
	}
	[ExcludeFromCodeCoverage]
	internal readonly struct Index : IEquatable<Index>
	{
		private static class ThrowHelper
		{
			[DoesNotReturn]
			public static void ThrowValueArgumentOutOfRange_NeedNonNegNumException()
			{
				throw new ArgumentOutOfRangeException("value", "Non-negative number required.");
			}
		}

		private readonly int _value;

		public static Index Start => new Index(0);

		public static Index End => new Index(-1);

		public int Value
		{
			get
			{
				if (_value < 0)
				{
					return ~_value;
				}
				return _value;
			}
		}

		public bool IsFromEnd => _value < 0;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Index(int value, bool fromEnd = false)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			if (fromEnd)
			{
				_value = ~value;
			}
			else
			{
				_value = value;
			}
		}

		private Index(int value)
		{
			_value = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Index FromStart(int value)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			return new Index(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Index FromEnd(int value)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			return new Index(~value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int GetOffset(int length)
		{
			int num = _value;
			if (IsFromEnd)
			{
				num += length + 1;
			}
			return num;
		}

		public override bool Equals([NotNullWhen(true)] object? value)
		{
			if (value is Index)
			{
				return _value == ((Index)value)._value;
			}
			return false;
		}

		public bool Equals(Index other)
		{
			return _value == other._value;
		}

		public override int GetHashCode()
		{
			return _value;
		}

		public static implicit operator Index(int value)
		{
			return FromStart(value);
		}

		public override string ToString()
		{
			if (IsFromEnd)
			{
				return ToStringFromEnd();
			}
			return ((uint)Value).ToString();
		}

		private string ToStringFromEnd()
		{
			return "^" + Value;
		}
	}
}
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.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class AsyncMethodBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public AsyncMethodBuilderAttribute(Type builderType)
		{
			BuilderType = builderType;
		}
	}
	[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.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.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : 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
	{
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class DisallowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public MaybeNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[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.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class NotNullIfNotNullAttribute : Attribute
	{
		public string ParameterName { get; }

		public NotNullIfNotNullAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[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 K4os.Compression.LZ4
{
	internal class AssemblyHook
	{
		private AssemblyHook()
		{
		}
	}
	public static class LZ4Codec
	{
		public const int Version = 192;

		public static bool Enforce32
		{
			get
			{
				return LL.Enforce32;
			}
			set
			{
				LL.Enforce32 = value;
			}
		}

		public static int MaximumOutputSize(int length)
		{
			return LL.LZ4_compressBound(length);
		}

		public unsafe static int Encode(byte* source, int sourceLength, byte* target, int targetLength, LZ4Level level = LZ4Level.L00_FAST)
		{
			if (sourceLength <= 0)
			{
				return 0;
			}
			int num = ((level < LZ4Level.L03_HC) ? LLxx.LZ4_compress_fast(source, target, sourceLength, targetLength, 1) : LLxx.LZ4_compress_HC(source, target, sourceLength, targetLength, (int)level));
			if (num > 0)
			{
				return num;
			}
			return -1;
		}

		public unsafe static int Encode(ReadOnlySpan<byte> source, Span<byte> target, LZ4Level level = LZ4Level.L00_FAST)
		{
			int length = source.Length;
			if (length <= 0)
			{
				return 0;
			}
			int length2 = target.Length;
			fixed (byte* source2 = source)
			{
				fixed (byte* target2 = target)
				{
					return Encode(source2, length, target2, length2, level);
				}
			}
		}

		public unsafe static int Encode(byte[] source, int sourceOffset, int sourceLength, byte[] target, int targetOffset, int targetLength, LZ4Level level = LZ4Level.L00_FAST)
		{
			source.Validate(sourceOffset, sourceLength);
			target.Validate(targetOffset, targetLength);
			fixed (byte* ptr = source)
			{
				fixed (byte* ptr2 = target)
				{
					return Encode(ptr + sourceOffset, sourceLength, ptr2 + targetOffset, targetLength, level);
				}
			}
		}

		public unsafe static int Decode(byte* source, int sourceLength, byte* target, int targetLength)
		{
			if (sourceLength <= 0)
			{
				return 0;
			}
			int num = LLxx.LZ4_decompress_safe(source, target, sourceLength, targetLength);
			if (num > 0)
			{
				return num;
			}
			return -1;
		}

		public unsafe static int PartialDecode(byte* source, int sourceLength, byte* target, int targetLength)
		{
			if (sourceLength <= 0)
			{
				return 0;
			}
			int num = LLxx.LZ4_decompress_safe_partial(source, target, sourceLength, targetLength);
			if (num > 0)
			{
				return num;
			}
			return -1;
		}

		public unsafe static int Decode(byte* source, int sourceLength, byte* target, int targetLength, byte* dictionary, int dictionaryLength)
		{
			if (sourceLength <= 0)
			{
				return 0;
			}
			int num = LLxx.LZ4_decompress_safe_usingDict(source, target, sourceLength, targetLength, dictionary, dictionaryLength);
			if (num > 0)
			{
				return num;
			}
			return -1;
		}

		public unsafe static int PartialDecode(ReadOnlySpan<byte> source, Span<byte> target)
		{
			int length = source.Length;
			if (length <= 0)
			{
				return 0;
			}
			fixed (byte* source2 = source)
			{
				fixed (byte* target2 = target)
				{
					return PartialDecode(source2, length, target2, target.Length);
				}
			}
		}

		public unsafe static int Decode(ReadOnlySpan<byte> source, Span<byte> target)
		{
			int length = source.Length;
			if (length <= 0)
			{
				return 0;
			}
			int length2 = target.Length;
			fixed (byte* source2 = source)
			{
				fixed (byte* target2 = target)
				{
					return Decode(source2, length, target2, length2);
				}
			}
		}

		public unsafe static int Decode(ReadOnlySpan<byte> source, Span<byte> target, ReadOnlySpan<byte> dictionary)
		{
			int length = source.Length;
			if (length <= 0)
			{
				return 0;
			}
			int length2 = target.Length;
			int length3 = dictionary.Length;
			fixed (byte* source2 = source)
			{
				fixed (byte* target2 = target)
				{
					fixed (byte* dictionary2 = dictionary)
					{
						return Decode(source2, length, target2, length2, dictionary2, length3);
					}
				}
			}
		}

		public unsafe static int Decode(byte[] source, int sourceOffset, int sourceLength, byte[] target, int targetOffset, int targetLength)
		{
			source.Validate(sourceOffset, sourceLength);
			target.Validate(targetOffset, targetLength);
			fixed (byte* ptr = source)
			{
				fixed (byte* ptr2 = target)
				{
					return Decode(ptr + sourceOffset, sourceLength, ptr2 + targetOffset, targetLength);
				}
			}
		}

		public unsafe static int Decode(byte[] source, int sourceOffset, int sourceLength, byte[] target, int targetOffset, int targetLength, byte[]? dictionary, int dictionaryOffset, int dictionaryLength)
		{
			source.Validate(sourceOffset, sourceLength);
			target.Validate(targetOffset, targetLength);
			dictionary.Validate(dictionaryOffset, dictionaryLength, allowNullIfEmpty: true);
			fixed (byte* ptr = source)
			{
				fixed (byte* ptr2 = target)
				{
					fixed (byte* ptr3 = dictionary)
					{
						return Decode(ptr + sourceOffset, sourceLength, ptr2 + targetOffset, targetLength, ptr3 + dictionaryOffset, dictionaryLength);
					}
				}
			}
		}
	}
	public enum LZ4Level
	{
		L00_FAST = 0,
		L03_HC = 3,
		L04_HC = 4,
		L05_HC = 5,
		L06_HC = 6,
		L07_HC = 7,
		L08_HC = 8,
		L09_HC = 9,
		L10_OPT = 10,
		L11_OPT = 11,
		L12_MAX = 12
	}
	public static class LZ4Pickler
	{
		private const int MAX_STACKALLOC = 1024;

		private const byte VersionMask = 7;

		public static byte[] Pickle(byte[] source, LZ4Level level = LZ4Level.L00_FAST)
		{
			return Pickle(source.AsSpan(), level);
		}

		public static byte[] Pickle(byte[] source, int sourceIndex, int sourceLength, LZ4Level level = LZ4Level.L00_FAST)
		{
			return Pickle(source.AsSpan(sourceIndex, sourceLength), level);
		}

		public unsafe static byte[] Pickle(byte* source, int length, LZ4Level level = LZ4Level.L00_FAST)
		{
			return Pickle(new Span<byte>(source, length), level);
		}

		public static byte[] Pickle(ReadOnlySpan<byte> source, LZ4Level level = LZ4Level.L00_FAST)
		{
			int length = source.Length;
			if (length == 0)
			{
				return Mem.Empty;
			}
			if (length <= 1024)
			{
				Span<byte> buffer = stackalloc byte[1024];
				return PickleWithBuffer(source, level, buffer);
			}
			PinnedMemory.Alloc(out var memory, length, zero: false);
			try
			{
				return PickleWithBuffer(source, level, memory.Span);
			}
			finally
			{
				memory.Free();
			}
		}

		private static byte[] PickleWithBuffer(ReadOnlySpan<byte> source, LZ4Level level, Span<byte> buffer)
		{
			int length = source.Length;
			int num = LZ4Codec.Encode(source, buffer, level);
			if (num <= 0 || num >= length)
			{
				byte[] array = new byte[GetUncompressedHeaderSize(0, length) + length];
				Span<byte> target = array.AsSpan();
				int start = EncodeUncompressedHeader(target, 0, length);
				source.CopyTo(target.Slice(start));
				return array;
			}
			int compressedHeaderSize = GetCompressedHeaderSize(0, length, num);
			byte[] array2 = new byte[compressedHeaderSize + num];
			Span<byte> target2 = array2.AsSpan();
			int start2 = EncodeCompressedHeader(target2, 0, compressedHeaderSize, length, num);
			buffer.Slice(0, num).CopyTo(target2.Slice(start2));
			return array2;
		}

		public static void Pickle<TBufferWriter>(ReadOnlySpan<byte> source, TBufferWriter writer, LZ4Level level = LZ4Level.L00_FAST) where TBufferWriter : IBufferWriter<byte>
		{
			if (writer == null)
			{
				throw new ArgumentNullException("writer");
			}
			int length = source.Length;
			if (length != 0)
			{
				int pessimisticHeaderSize = GetPessimisticHeaderSize(0, length);
				Span<byte> span = ((IBufferWriter<byte>)writer).GetSpan(pessimisticHeaderSize + length);
				int num = LZ4Codec.Encode(source, span.Slice(pessimisticHeaderSize, length), level);
				if (num <= 0 || num >= length)
				{
					int num2 = EncodeUncompressedHeader(span, 0, length);
					source.CopyTo(span.Slice(num2));
					((IBufferWriter<byte>)writer).Advance(num2 + length);
				}
				else
				{
					int num3 = EncodeCompressedHeader(span, 0, pessimisticHeaderSize, length, num);
					((IBufferWriter<byte>)writer).Advance(num3 + num);
				}
			}
		}

		public static void Pickle(ReadOnlySpan<byte> source, IBufferWriter<byte> writer, LZ4Level level = LZ4Level.L00_FAST)
		{
			Pickle<IBufferWriter<byte>>(source, writer, level);
		}

		private static int GetPessimisticHeaderSize(int version, int sourceLength)
		{
			if (version == 0)
			{
				return 1 + EffectiveSizeOf(sourceLength);
			}
			throw UnexpectedVersion(version);
		}

		private static int GetUncompressedHeaderSize(int version, int sourceLength)
		{
			if (version == 0)
			{
				return 1;
			}
			throw UnexpectedVersion(version);
		}

		private static int GetCompressedHeaderSize(int version, int sourceLength, int encodedLength)
		{
			if (version == 0)
			{
				return 1 + EffectiveSizeOf(sourceLength - encodedLength);
			}
			throw UnexpectedVersion(version);
		}

		private static int EncodeUncompressedHeader(Span<byte> target, int version, int sourceLength)
		{
			if (version == 0)
			{
				return EncodeUncompressedHeaderV0(target);
			}
			throw UnexpectedVersion(version);
		}

		private static int EncodeUncompressedHeaderV0(Span<byte> target)
		{
			target[0] = 0;
			return 1;
		}

		private static int EncodeCompressedHeader(Span<byte> target, int version, int headerSize, int sourceLength, int encodedLength)
		{
			if (version == 0)
			{
				return EncodeCompressedHeaderV0(target, headerSize, sourceLength, encodedLength);
			}
			throw UnexpectedVersion(version);
		}

		private static int EncodeCompressedHeaderV0(Span<byte> target, int headerSize, int sourceLength, int encodedLength)
		{
			int value = sourceLength - encodedLength;
			int num = headerSize - 1;
			target[0] = EncodeHeaderByteV0(num);
			PokeN(target.Slice(1), value, num);
			return 1 + num;
		}

		private unsafe static void PokeN(Span<byte> target, int value, int size)
		{
			if (size < 0 || size > 4 || target.Length < size)
			{
				throw new ArgumentException($"Unexpected size: {size}");
			}
			System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(ref target[0], ref *(byte*)(&value), (uint)size);
		}

		private static byte EncodeHeaderByteV0(int sizeOfDiff)
		{
			return (byte)(0u | (uint)((EncodeSizeOf(sizeOfDiff) & 3) << 6));
		}

		private static int EffectiveSizeOf(int value)
		{
			if (value > 255)
			{
				if (value <= 65535)
				{
					return 2;
				}
			}
			else if (value >= 0)
			{
				return 1;
			}
			return 4;
		}

		private static int EncodeSizeOf(int size)
		{
			if (size == 4)
			{
				return 3;
			}
			return size;
		}

		private static Exception UnexpectedVersion(int version)
		{
			return new ArgumentException($"Unexpected pickle version: {version}");
		}

		public static byte[] Unpickle(byte[] source)
		{
			return Unpickle(source.AsSpan());
		}

		public static byte[] Unpickle(byte[] source, int index, int count)
		{
			return Unpickle(source.AsSpan(index, count));
		}

		public unsafe static byte[] Unpickle(byte* source, int count)
		{
			return Unpickle(new Span<byte>(source, count));
		}

		public static byte[] Unpickle(ReadOnlySpan<byte> source)
		{
			if (source.Length == 0)
			{
				return Mem.Empty;
			}
			PickleHeader header = DecodeHeader(source);
			int num = UnpickledSize(in header);
			if (num == 0)
			{
				return Mem.Empty;
			}
			byte[] array = new byte[num];
			UnpickleCore(in header, source, array);
			return array;
		}

		public static void Unpickle<TBufferWriter>(ReadOnlySpan<byte> source, TBufferWriter writer) where TBufferWriter : IBufferWriter<byte>
		{
			writer.Required("writer");
			if (source.Length != 0)
			{
				PickleHeader header = DecodeHeader(source);
				int num = UnpickledSize(in header);
				Span<byte> target = ((IBufferWriter<byte>)writer).GetSpan(num).Slice(0, num);
				UnpickleCore(in header, source, target);
				((IBufferWriter<byte>)writer).Advance(num);
			}
		}

		public static void Unpickle(ReadOnlySpan<byte> source, IBufferWriter<byte> writer)
		{
			Unpickle<IBufferWriter<byte>>(source, writer);
		}

		public static int UnpickledSize(ReadOnlySpan<byte> source)
		{
			PickleHeader header = DecodeHeader(source);
			return UnpickledSize(in header);
		}

		private static int UnpickledSize(in PickleHeader header)
		{
			return header.ResultLength;
		}

		public static void Unpickle(ReadOnlySpan<byte> source, Span<byte> output)
		{
			if (source.Length != 0)
			{
				PickleHeader header = DecodeHeader(source);
				UnpickleCore(in header, source, output);
			}
		}

		private static void UnpickleCore(in PickleHeader header, ReadOnlySpan<byte> source, Span<byte> target)
		{
			ReadOnlySpan<byte> source2 = source.Slice(header.DataOffset);
			int num = UnpickledSize(in header);
			int length = target.Length;
			if (length != num)
			{
				throw CorruptedPickle($"Output buffer size ({length}) does not match expected value ({num})");
			}
			if (!header.IsCompressed)
			{
				source2.CopyTo(target);
				return;
			}
			int num2 = LZ4Codec.Decode(source2, target);
			if (num2 == num)
			{
				return;
			}
			throw CorruptedPickle($"Expected to decode {num} bytes but {num2} has been decoded");
		}

		private static PickleHeader DecodeHeader(ReadOnlySpan<byte> source)
		{
			int num = source[0] & 7;
			if (num == 0)
			{
				return DecodeHeaderV0(source);
			}
			throw CorruptedPickle($"Version {num} is not recognized");
		}

		private static PickleHeader DecodeHeaderV0(ReadOnlySpan<byte> source)
		{
			int num = (source[0] >> 6) & 3;
			int num2 = ((num != 3) ? num : 4);
			int num3 = num2;
			ushort num4 = (ushort)(1 + num3);
			int num5 = source.Length - num4;
			if (num5 < 0)
			{
				throw CorruptedPickle($"Unexpected data length: {num5}");
			}
			int num6 = ((num3 != 0) ? PeekN(source.Slice(1), num3) : 0);
			int resultLength = num5 + num6;
			return new PickleHeader(num4, resultLength, num6 != 0);
		}

		private unsafe static int PeekN(ReadOnlySpan<byte> bytes, int size)
		{
			int result = 0;
			if (size < 0 || size > 4 || size > bytes.Length)
			{
				throw CorruptedPickle($"Unexpected field size: {size}");
			}
			fixed (byte* ptr = bytes)
			{
				System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned((void*)(&result), (void*)ptr, (uint)size);
			}
			return result;
		}

		private static Exception CorruptedPickle(string message)
		{
			return new InvalidDataException("Pickle is corrupted: " + message);
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	internal readonly struct PickleHeader
	{
		public ushort DataOffset { get; }

		public ushort Flags { get; }

		public int ResultLength { get; }

		public bool IsCompressed => (Flags & 1) != 0;

		public PickleHeader(ushort dataOffset, int resultLength, bool compressed)
		{
			DataOffset = dataOffset;
			ResultLength = resultLength;
			Flags = (ushort)((compressed ? 1u : 0u) | 0u);
		}
	}
}
namespace K4os.Compression.LZ4.Internal
{
	public static class BufferPool
	{
		public const int MinPooledSize = 512;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool ShouldBePooled(int length)
		{
			return length >= 512;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static byte[] Rent(int size, bool zero)
		{
			byte[] array = ArrayPool<byte>.Shared.Rent(size);
			if (zero)
			{
				array.AsSpan(0, size).Clear();
			}
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static byte[] Alloc(int size, bool zero = false)
		{
			if (!ShouldBePooled(size))
			{
				return new byte[size];
			}
			return Rent(size, zero);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsPooled(byte[] buffer)
		{
			return ShouldBePooled(buffer.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void Free(byte[]? buffer)
		{
			if (buffer != null && IsPooled(buffer))
			{
				ArrayPool<byte>.Shared.Return(buffer);
			}
		}
	}
	public class Mem
	{
		public const int K1 = 1024;

		public const int K2 = 2048;

		public const int K4 = 4096;

		public const int K8 = 8192;

		public const int K16 = 16384;

		public const int K32 = 32768;

		public const int K64 = 65536;

		public const int K128 = 131072;

		public const int K256 = 262144;

		public const int K512 = 524288;

		public const int M1 = 1048576;

		public const int M4 = 4194304;

		public static readonly byte[] Empty = Array.Empty<byte>();

		public unsafe static bool System32
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return sizeof(void*) < 8;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int RoundUp(int value, int step)
		{
			return (value + step - 1) / step * step;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal unsafe static void CpBlk(void* target, void* source, uint length)
		{
			System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(target, source, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal unsafe static void ZBlk(void* target, byte value, uint length)
		{
			System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(target, value, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Copy(byte* target, byte* source, int length)
		{
			if (length > 0)
			{
				CpBlk(target, source, (uint)length);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Move(byte* target, byte* source, int length)
		{
			Buffer.MemoryCopy(source, target, length, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void* Alloc(int size)
		{
			return Marshal.AllocHGlobal(size).ToPointer();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static byte* Zero(byte* target, int length)
		{
			return Fill(target, 0, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static byte* Fill(byte* target, byte value, int length)
		{
			if (length > 0)
			{
				ZBlk(target, value, (uint)length);
			}
			return target;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void* AllocZero(int size)
		{
			return Zero((byte*)Alloc(size), size);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Free(void* ptr)
		{
			Marshal.FreeHGlobal(new IntPtr(ptr));
		}

		public unsafe static T* CloneArray<T>(T[] array) where T : unmanaged
		{
			int num = System.Runtime.CompilerServices.Unsafe.SizeOf<T>() * array.Length;
			void* intPtr = Alloc(num);
			fixed (byte* ptr = &System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref array[0]))
			{
				void* source = ptr;
				Copy((byte*)intPtr, (byte*)source, num);
			}
			return (T*)intPtr;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static byte Peek1(void* p)
		{
			return *(byte*)p;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Poke1(void* p, byte v)
		{
			*(byte*)p = v;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static ushort Peek2(void* p)
		{
			ushort result = default(ushort);
			CpBlk(&result, p, 2u);
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Poke2(void* p, ushort v)
		{
			CpBlk(p, &v, 2u);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static uint Peek4(void* p)
		{
			uint result = default(uint);
			CpBlk(&result, p, 4u);
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Poke4(void* p, uint v)
		{
			CpBlk(p, &v, 4u);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static ulong Peek8(void* p)
		{
			ulong result = default(ulong);
			CpBlk(&result, p, 8u);
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Poke8(void* p, ulong v)
		{
			CpBlk(p, &v, 8u);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Copy1(byte* target, byte* source)
		{
			*target = *source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Copy2(byte* target, byte* source)
		{
			CpBlk(target, source, 2u);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Copy4(byte* target, byte* source)
		{
			CpBlk(target, source, 4u);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Copy8(byte* target, byte* source)
		{
			CpBlk(target, source, 8u);
		}
	}
	public struct PinnedMemory
	{
		private unsafe byte* _pointer;

		private GCHandle _handle;

		private int _size;

		public static int MaxPooledSize { get; set; } = 1048576;


		public unsafe readonly byte* Pointer
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return _pointer;
			}
		}

		public unsafe Span<byte> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return new Span<byte>(Pointer, _size);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe readonly T* Reference<T>() where T : unmanaged
		{
			return (T*)_pointer;
		}

		public static PinnedMemory Alloc(int size, bool zero = true)
		{
			Alloc(out var memory, size, zero);
			return memory;
		}

		public static void Alloc(out PinnedMemory memory, int size, bool zero = true)
		{
			if (size <= 0)
			{
				throw new ArgumentOutOfRangeException("size");
			}
			if (size > MaxPooledSize)
			{
				AllocateNative(out memory, size, zero);
			}
			else
			{
				RentManagedFromPool(out memory, size, zero);
			}
		}

		public unsafe static void Alloc<T>(out PinnedMemory memory, bool zero = true) where T : unmanaged
		{
			Alloc(out memory, sizeof(T), zero);
		}

		private unsafe static void AllocateNative(out PinnedMemory memory, int size, bool zero)
		{
			void* pointer = (zero ? Mem.AllocZero(size) : Mem.Alloc(size));
			GC.AddMemoryPressure(size);
			memory._pointer = (byte*)pointer;
			memory._handle = default(GCHandle);
			memory._size = size;
		}

		private unsafe static void RentManagedFromPool(out PinnedMemory memory, int size, bool zero)
		{
			GCHandle handle = GCHandle.Alloc(BufferPool.Alloc(size, zero), GCHandleType.Pinned);
			byte* pointer = (byte*)(void*)handle.AddrOfPinnedObject();
			memory._pointer = pointer;
			memory._handle = handle;
			memory._size = size;
		}

		public unsafe void Clear()
		{
			if (_size > 0 && _pointer != null)
			{
				Mem.Zero(_pointer, _size);
			}
		}

		public unsafe void Free()
		{
			if (_handle.IsAllocated)
			{
				ReleaseManaged();
			}
			else if (_pointer != null)
			{
				ReleaseNative();
			}
			ClearFields();
		}

		private void ReleaseManaged()
		{
			byte[] buffer = (_handle.IsAllocated ? ((byte[])_handle.Target) : null);
			_handle.Free();
			BufferPool.Free(buffer);
		}

		private unsafe void ReleaseNative()
		{
			GC.RemoveMemoryPressure(_size);
			Mem.Free(_pointer);
		}

		private unsafe void ClearFields()
		{
			_pointer = null;
			_handle = default(GCHandle);
			_size = 0;
		}
	}
	public abstract class UnmanagedResources : IDisposable
	{
		private int _disposed;

		public bool IsDisposed => Interlocked.CompareExchange(ref _disposed, 0, 0) != 0;

		protected void ThrowIfDisposed()
		{
			if (IsDisposed)
			{
				throw new ObjectDisposedException(GetType().FullName + " is already disposed");
			}
		}

		protected virtual void ReleaseUnmanaged()
		{
		}

		protected virtual void ReleaseManaged()
		{
		}

		protected virtual void Dispose(bool disposing)
		{
			if (Interlocked.CompareExchange(ref _disposed, 1, 0) == 0)
			{
				ReleaseUnmanaged();
				if (disposing)
				{
					ReleaseManaged();
				}
			}
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		~UnmanagedResources()
		{
			Dispose(disposing: false);
		}
	}
	public class Mem32 : Mem
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static uint PeekW(void* p)
		{
			return Mem.Peek4(p);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void PokeW(void* p, uint v)
		{
			Mem.Poke4(p, v);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Copy16(byte* target, byte* source)
		{
			Mem.Copy8(target, source);
			Mem.Copy8(target + 8, source + 8);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Copy18(byte* target, byte* source)
		{
			Mem.Copy8(target, source);
			Mem.Copy8(target + 8, source + 8);
			Mem.Copy2(target + 16, source + 16);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void WildCopy8(byte* target, byte* source, void* limit)
		{
			do
			{
				Mem.Copy8(target, source);
				target += 8;
				source += 8;
			}
			while (target < limit);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void WildCopy32(byte* target, byte* source, void* limit)
		{
			do
			{
				Copy16(target, source);
				Copy16(target + 16, source + 16);
				target += 32;
				source += 32;
			}
			while (target < limit);
		}
	}
	public class Mem64 : Mem
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public new unsafe static ushort Peek2(void* p)
		{
			return *(ushort*)p;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public new unsafe static void Poke2(void* p, ushort v)
		{
			*(ushort*)p = v;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public new unsafe static uint Peek4(void* p)
		{
			return *(uint*)p;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public new unsafe static void Poke4(void* p, uint v)
		{
			*(uint*)p = v;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public new unsafe static void Copy1(byte* target, byte* source)
		{
			*target = *source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public new unsafe static void Copy2(byte* target, byte* source)
		{
			*(short*)target = *(short*)source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public new unsafe static void Copy4(byte* target, byte* source)
		{
			*(int*)target = *(int*)source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public new unsafe static ulong Peek8(void* p)
		{
			return *(ulong*)p;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public new unsafe static void Poke8(void* p, ulong v)
		{
			*(ulong*)p = v;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public new unsafe static void Copy8(byte* target, byte* source)
		{
			*(long*)target = *(long*)source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static ulong PeekW(void* p)
		{
			return Peek8(p);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void PokeW(void* p, ulong v)
		{
			Poke8(p, v);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Copy16(byte* target, byte* source)
		{
			Copy8(target, source);
			Copy8(target + 8, source + 8);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Copy18(byte* target, byte* source)
		{
			Copy8(target, source);
			Copy8(target + 8, source + 8);
			Copy2(target + 16, source + 16);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void WildCopy8(byte* target, byte* source, void* limit)
		{
			do
			{
				Copy8(target, source);
				target += 8;
				source += 8;
			}
			while (target < limit);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void WildCopy32(byte* target, byte* source, void* limit)
		{
			do
			{
				Copy16(target, source);
				Copy16(target + 16, source + 16);
				target += 32;
				source += 32;
			}
			while (target < limit);
		}
	}
}
namespace K4os.Compression.LZ4.Engine
{
	public enum Algorithm
	{
		X32,
		X64
	}
	internal class LL
	{
		public struct LZ4_stream_t
		{
			public unsafe fixed uint hashTable[4096];

			public uint currentOffset;

			public bool dirty;

			public tableType_t tableType;

			public unsafe byte* dictionary;

			public unsafe LZ4_stream_t* dictCtx;

			public uint dictSize;
		}

		public struct LZ4_streamDecode_t
		{
			public unsafe byte* externalDict;

			public uint extDictSize;

			public unsafe byte* prefixEnd;

			public uint prefixSize;
		}

		public enum limitedOutput_directive
		{
			notLimited,
			limitedOutput,
			fillOutput
		}

		public enum tableType_t
		{
			clearedTable,
			byPtr,
			byU32,
			byU16
		}

		public enum dict_directive
		{
			noDict,
			withPrefix64k,
			usingExtDict,
			usingDictCtx
		}

		public enum dictIssue_directive
		{
			noDictIssue,
			dictSmall
		}

		public enum endCondition_directive
		{
			endOnOutputSize,
			endOnInputSize
		}

		public enum earlyEnd_directive
		{
			full,
			partial
		}

		protected enum variable_length_error
		{
			loop_error = -2,
			initial_error,
			ok
		}

		public enum dictCtx_directive
		{
			noDictCtx,
			usingDictCtxHc
		}

		public struct LZ4_streamHC_t
		{
			public unsafe fixed uint hashTable[32768];

			public unsafe fixed ushort chainTable[65536];

			public unsafe byte* end;

			public unsafe byte* @base;

			public unsafe byte* dictBase;

			public uint dictLimit;

			public uint lowLimit;

			public uint nextToUpdate;

			public short compressionLevel;

			public bool favorDecSpeed;

			public bool dirty;

			public unsafe LZ4_streamHC_t* dictCtx;
		}

		protected enum repeat_state_e
		{
			rep_untested,
			rep_not,
			rep_confirmed
		}

		public enum HCfavor_e
		{
			favorCompressionRatio,
			favorDecompressionSpeed
		}

		public struct LZ4HC_match_t
		{
			public int off;

			public int len;
		}

		public struct LZ4HC_optimal_t
		{
			public int price;

			public int off;

			public int mlen;

			public int litlen;
		}

		public enum lz4hc_strat_e
		{
			lz4hc,
			lz4opt
		}

		public struct cParams_t
		{
			public lz4hc_strat_e strat;

			public uint nbSearches;

			public uint targetLength;

			public cParams_t(lz4hc_strat_e strat, uint nbSearches, uint targetLength)
			{
				this.strat = strat;
				this.nbSearches = nbSearches;
				this.targetLength = targetLength;
			}
		}

		private static readonly uint[] _inc32table = new uint[8] { 0u, 1u, 2u, 1u, 0u, 4u, 4u, 4u };

		private static readonly int[] _dec64table = new int[8] { 0, 0, 0, -1, -4, 1, 2, 3 };

		protected unsafe static readonly uint* inc32table = Mem.CloneArray(_inc32table);

		protected unsafe static readonly int* dec64table = Mem.CloneArray(_dec64table);

		protected const int LZ4_MEMORY_USAGE = 14;

		protected const int LZ4_MAX_INPUT_SIZE = 2113929216;

		protected const int LZ4_DISTANCE_MAX = 65535;

		protected const int LZ4_DISTANCE_ABSOLUTE_MAX = 65535;

		protected const int LZ4_HASHLOG = 12;

		protected const int LZ4_HASHTABLESIZE = 16384;

		protected const int LZ4_HASH_SIZE_U32 = 4096;

		protected const int ACCELERATION_DEFAULT = 1;

		protected const int MINMATCH = 4;

		protected const int WILDCOPYLENGTH = 8;

		protected const int LASTLITERALS = 5;

		protected const int MFLIMIT = 12;

		protected const int MATCH_SAFEGUARD_DISTANCE = 12;

		protected const int FASTLOOP_SAFE_DISTANCE = 64;

		protected const int LZ4_minLength = 13;

		protected const int KB = 1024;

		protected const int MB = 1048576;

		protected const uint GB = 1073741824u;

		protected const int ML_BITS = 4;

		protected const uint ML_MASK = 15u;

		protected const int RUN_BITS = 4;

		protected const uint RUN_MASK = 15u;

		protected const int OPTIMAL_ML = 18;

		protected const int LZ4_OPT_NUM = 4096;

		protected const int LZ4_64Klimit = 65547;

		protected const int LZ4_skipTrigger = 6;

		protected const int LZ4HC_DICTIONARY_LOGSIZE = 16;

		protected const int LZ4HC_MAXD = 65536;

		protected const int LZ4HC_MAXD_MASK = 65535;

		protected const int LZ4HC_HASH_LOG = 15;

		protected const int LZ4HC_HASHTABLESIZE = 32768;

		protected const int LZ4HC_HASH_MASK = 32767;

		protected const int LZ4HC_CLEVEL_MIN = 3;

		protected const int LZ4HC_CLEVEL_DEFAULT = 9;

		protected const int LZ4HC_CLEVEL_OPT_MIN = 10;

		protected const int LZ4HC_CLEVEL_MAX = 12;

		public static bool Enforce32 { get; set; } = false;


		public static Algorithm Algorithm
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if (!Enforce32 && !Mem.System32)
				{
					return Algorithm.X64;
				}
				return Algorithm.X32;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static int LZ4_sizeofStateHC()
		{
			return sizeof(LZ4_streamHC_t);
		}

		public unsafe static void LZ4_setCompressionLevel(LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel)
		{
			if (compressionLevel < 1)
			{
				compressionLevel = 9;
			}
			if (compressionLevel > 12)
			{
				compressionLevel = 12;
			}
			LZ4_streamHCPtr->compressionLevel = (short)compressionLevel;
		}

		public unsafe static void LZ4_favorDecompressionSpeed(LZ4_streamHC_t* LZ4_streamHCPtr, int favor)
		{
			LZ4_streamHCPtr->favorDecSpeed = favor != 0;
		}

		public unsafe static LZ4_streamHC_t* LZ4_initStreamHC(void* buffer, int size)
		{
			if (buffer == null)
			{
				return null;
			}
			if (size < sizeof(LZ4_streamHC_t))
			{
				return null;
			}
			((LZ4_streamHC_t*)buffer)->end = (byte*)(-1);
			((LZ4_streamHC_t*)buffer)->@base = null;
			((LZ4_streamHC_t*)buffer)->dictCtx = null;
			((LZ4_streamHC_t*)buffer)->favorDecSpeed = false;
			((LZ4_streamHC_t*)buffer)->dirty = false;
			LZ4_setCompressionLevel((LZ4_streamHC_t*)buffer, 9);
			return (LZ4_streamHC_t*)buffer;
		}

		public unsafe static LZ4_streamHC_t* LZ4_initStreamHC(LZ4_streamHC_t* stream)
		{
			return LZ4_initStreamHC(stream, sizeof(LZ4_streamHC_t));
		}

		public unsafe static void LZ4_resetStreamHC_fast(LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel)
		{
			if (LZ4_streamHCPtr->dirty)
			{
				LZ4_initStreamHC(LZ4_streamHCPtr);
			}
			else
			{
				byte** end = &LZ4_streamHCPtr->end;
				*end -= LZ4_streamHCPtr->@base;
				LZ4_streamHCPtr->@base = null;
				LZ4_streamHCPtr->dictCtx = null;
			}
			LZ4_setCompressionLevel(LZ4_streamHCPtr, compressionLevel);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static uint HASH_FUNCTION(uint value)
		{
			return (uint)((int)value * -1640531535) >> 17;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		protected unsafe static ref ushort DELTANEXTU16(ushort* table, uint pos)
		{
			return ref table[(int)(ushort)pos];
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static uint LZ4HC_hashPtr(void* ptr)
		{
			return HASH_FUNCTION(Mem.Peek4(ptr));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void LZ4HC_Insert(LZ4_streamHC_t* hc4, byte* ip)
		{
			ushort* table = hc4->chainTable;
			uint* ptr = hc4->hashTable;
			byte* @base = hc4->@base;
			uint num = (uint)(ip - @base);
			for (uint num2 = hc4->nextToUpdate; num2 < num; num2++)
			{
				uint num3 = LZ4HC_hashPtr(@base + num2);
				uint num4 = num2 - ptr[num3];
				if (num4 > 65535)
				{
					num4 = 65535u;
				}
				DELTANEXTU16(table, num2) = (ushort)num4;
				ptr[num3] = num2;
			}
			hc4->nextToUpdate = num;
		}

		public unsafe static void LZ4HC_setExternalDict(LZ4_streamHC_t* ctxPtr, byte* newBlock)
		{
			if (ctxPtr->end >= ctxPtr->@base + ctxPtr->dictLimit + 4)
			{
				LZ4HC_Insert(ctxPtr, ctxPtr->end - 3);
			}
			ctxPtr->lowLimit = ctxPtr->dictLimit;
			ctxPtr->dictLimit = (uint)(ctxPtr->end - ctxPtr->@base);
			ctxPtr->dictBase = ctxPtr->@base;
			ctxPtr->@base = newBlock - ctxPtr->dictLimit;
			ctxPtr->end = newBlock;
			ctxPtr->nextToUpdate = ctxPtr->dictLimit;
			ctxPtr->dictCtx = null;
		}

		public unsafe static void LZ4HC_clearTables(LZ4_streamHC_t* hc4)
		{
			Mem.Fill((byte*)hc4->hashTable, 0, 131072);
			Mem.Fill((byte*)hc4->chainTable, byte.MaxValue, 131072);
		}

		public unsafe static void LZ4HC_init_internal(LZ4_streamHC_t* hc4, byte* start)
		{
			long num = hc4->end - hc4->@base;
			if (num < 0 || num > 1073741824)
			{
				LZ4HC_clearTables(hc4);
				num = 0L;
			}
			num += 65536;
			hc4->nextToUpdate = (uint)num;
			hc4->@base = start - num;
			hc4->end = start;
			hc4->dictBase = start - num;
			hc4->dictLimit = (uint)num;
			hc4->lowLimit = (uint)num;
		}

		public unsafe static int LZ4_saveDictHC(LZ4_streamHC_t* LZ4_streamHCPtr, byte* safeBuffer, int dictSize)
		{
			int num = (int)(LZ4_streamHCPtr->end - (LZ4_streamHCPtr->@base + LZ4_streamHCPtr->dictLimit));
			if (dictSize > 65536)
			{
				dictSize = 65536;
			}
			if (dictSize < 4)
			{
				dictSize = 0;
			}
			if (dictSize > num)
			{
				dictSize = num;
			}
			Mem.Move(safeBuffer, LZ4_streamHCPtr->end - dictSize, dictSize);
			uint num2 = (uint)(LZ4_streamHCPtr->end - LZ4_streamHCPtr->@base);
			LZ4_streamHCPtr->end = safeBuffer + dictSize;
			LZ4_streamHCPtr->@base = LZ4_streamHCPtr->end - num2;
			LZ4_streamHCPtr->dictLimit = num2 - (uint)dictSize;
			LZ4_streamHCPtr->lowLimit = num2 - (uint)dictSize;
			if (LZ4_streamHCPtr->nextToUpdate < LZ4_streamHCPtr->dictLimit)
			{
				LZ4_streamHCPtr->nextToUpdate = LZ4_streamHCPtr->dictLimit;
			}
			return dictSize;
		}

		public unsafe static int LZ4_loadDictHC(LZ4_streamHC_t* LZ4_streamHCPtr, byte* dictionary, int dictSize)
		{
			if (dictSize > 65536)
			{
				dictionary += dictSize - 65536;
				dictSize = 65536;
			}
			int compressionLevel = LZ4_streamHCPtr->compressionLevel;
			LZ4_initStreamHC(LZ4_streamHCPtr);
			LZ4_setCompressionLevel(LZ4_streamHCPtr, compressionLevel);
			LZ4HC_init_internal(LZ4_streamHCPtr, dictionary);
			LZ4_streamHCPtr->end = dictionary + dictSize;
			if (dictSize >= 4)
			{
				LZ4HC_Insert(LZ4_streamHCPtr, LZ4_streamHCPtr->end - 3);
			}
			return dictSize;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint LZ4HC_rotl32(uint x, int r)
		{
			return (x << r) | (x >> 32 - r);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool LZ4HC_protectDictEnd(uint dictLimit, uint matchIndex)
		{
			return dictLimit - 1 - matchIndex >= 3;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static int LZ4HC_countBack(byte* ip, byte* match, byte* iMin, byte* mMin)
		{
			int num = 0;
			int num2 = (int)MAX(iMin - ip, mMin - match);
			while (num > num2 && ip[num - 1] == match[num - 1])
			{
				num--;
			}
			return num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static uint LZ4HC_reverseCountPattern(byte* ip, byte* iLow, uint pattern)
		{
			byte* ptr = ip;
			while (ip >= iLow + 4 && Mem.Peek4(ip - 4) == pattern)
			{
				ip -= 4;
			}
			byte* ptr2 = (byte*)(&pattern) + 3;
			while (ip > iLow && ip[-1] == *ptr2)
			{
				ip--;
				ptr2--;
			}
			return (uint)(ptr - ip);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint LZ4HC_rotatePattern(uint rotate, uint pattern)
		{
			uint num = (rotate & 3) << 3;
			if (num == 0)
			{
				return pattern;
			}
			return LZ4HC_rotl32(pattern, (int)num);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LZ4HC_literalsPrice(int litlen)
		{
			int num = litlen;
			if (litlen >= 15)
			{
				num += 1 + (litlen - 15) / 255;
			}
			return num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LZ4HC_sequencePrice(int litlen, int mlen)
		{
			int num = 3;
			num += LZ4HC_literalsPrice(litlen);
			if (mlen >= 19)
			{
				num += 1 + (mlen - 19) / 255;
			}
			return num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[Conditional("DEBUG")]
		public static void Assert(bool value, [CallerArgumentExpression("value")] string message = null)
		{
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int LZ4_compressBound(int isize)
		{
			if (isize <= 2113929216)
			{
				return isize + isize / 255 + 16;
			}
			return 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int LZ4_decoderRingBufferSize(int isize)
		{
			return 65550 + isize;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		protected static uint LZ4_hash4(uint sequence, tableType_t tableType)
		{
			int num = ((tableType == tableType_t.byU16) ? 13 : 12);
			return (uint)((int)sequence * -1640531535) >> 32 - num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		protected static uint LZ4_hash5(ulong sequence, tableType_t tableType)
		{
			int num = ((tableType == tableType_t.byU16) ? 13 : 12);
			return (uint)((sequence << 24) * 889523592379L >> 64 - num);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		protected unsafe static void LZ4_clearHash(uint h, void* tableBase, tableType_t tableType)
		{
			switch (tableType)
			{
			case tableType_t.byPtr:
				*(IntPtr*)((byte*)tableBase + h * sizeof(byte*)) = (nint)0;
				break;
			case tableType_t.byU32:
				*(int*)((byte*)tableBase + (long)h * 4L) = 0;
				break;
			case tableType_t.byU16:
				*(short*)((byte*)tableBase + (long)h * 2L) = 0;
				break;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		protected unsafe static void LZ4_putIndexOnHash(uint idx, uint h, void* tableBase, tableType_t tableType)
		{
			switch (tableType)
			{
			case tableType_t.byU32:
				*(uint*)((byte*)tableBase + (long)h * 4L) = idx;
				break;
			case tableType_t.byU16:
				*(ushort*)((byte*)tableBase + (long)h * 2L) = (ushort)idx;
				break;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		protected unsafe static void LZ4_putPositionOnHash(byte* p, uint h, void* tableBase, tableType_t tableType, byte* srcBase)
		{
			switch (tableType)
			{
			case tableType_t.byPtr:
				*(byte**)((byte*)tableBase + h * sizeof(byte*)) = p;
				break;
			case tableType_t.byU32:
				*(int*)((byte*)tableBase + (long)h * 4L) = (int)(p - srcBase);
				break;
			case tableType_t.byU16:
				*(ushort*)((byte*)tableBase + (long)h * 2L) = (ushort)(p - srcBase);
				break;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		protected unsafe static uint LZ4_getIndexOnHash(uint h, void* tableBase, tableType_t tableType)
		{
			return tableType switch
			{
				tableType_t.byU32 => *(uint*)((byte*)tableBase + (long)h * 4L), 
				tableType_t.byU16 => *(ushort*)((byte*)tableBase + (long)h * 2L), 
				_ => 0u, 
			};
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		protected unsafe static byte* LZ4_getPositionOnHash(uint h, void* tableBase, tableType_t tableType, byte* srcBase)
		{
			return tableType switch
			{
				tableType_t.byPtr => *(byte**)((byte*)tableBase + h * sizeof(byte*)), 
				tableType_t.byU32 => (uint)(*(int*)((byte*)tableBase + (long)h * 4L)) + srcBase, 
				_ => (int)(*(ushort*)((byte*)tableBase + (long)h * 2L)) + srcBase, 
			};
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int MIN(int a, int b)
		{
			if (a >= b)
			{
				return b;
			}
			return a;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint MIN(uint a, uint b)
		{
			if (a >= b)
			{
				return b;
			}
			return a;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint MAX(uint a, uint b)
		{
			if (a >= b)
			{
				return a;
			}
			return b;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static long MAX(long a, long b)
		{
			if (a >= b)
			{
				return a;
			}
			return b;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static long MIN(long a, long b)
		{
			if (a >= b)
			{
				return b;
			}
			return a;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		protected unsafe static uint LZ4_readVLE(byte** ip, byte* lencheck, bool loop_check, bool initial_check, variable_length_error* error)
		{
			uint num = 0u;
			if (initial_check && *ip >= lencheck)
			{
				*error = variable_length_error.initial_error;
				return num;
			}
			uint num2;
			do
			{
				num2 = *(*ip);
				(*ip)++;
				num += num2;
				if (loop_check && *ip >= lencheck)
				{
					*error = variable_length_error.loop_error;
					return num;
				}
			}
			while (num2 == 255);
			return num;
		}

		public unsafe static int LZ4_saveDict(LZ4_stream_t* LZ4_dict, byte* safeBuffer, int dictSize)
		{
			byte* ptr = LZ4_dict->dictionary + LZ4_dict->dictSize;
			if ((uint)dictSize > 65536u)
			{
				dictSize = 65536;
			}
			if ((uint)dictSize > LZ4_dict->dictSize)
			{
				dictSize = (int)LZ4_dict->dictSize;
			}
			Mem.Move(safeBuffer, ptr - dictSize, dictSize);
			LZ4_dict->dictionary = safeBuffer;
			LZ4_dict->dictSize = (uint)dictSize;
			return dictSize;
		}

		public unsafe static LZ4_stream_t* LZ4_initStream(LZ4_stream_t* buffer)
		{
			Mem.Zero((byte*)buffer, sizeof(LZ4_stream_t));
			return buffer;
		}

		public unsafe static void LZ4_setStreamDecode(LZ4_streamDecode_t* LZ4_streamDecode, byte* dictionary, int dictSize)
		{
			LZ4_streamDecode->prefixSize = (uint)dictSize;
			LZ4_streamDecode->prefixEnd = dictionary + dictSize;
			LZ4_streamDecode->externalDict = null;
			LZ4_streamDecode->extDictSize = 0u;
		}
	}
	internal static class LLxx
	{
		private static NotImplementedException AlgorithmNotImplemented(string action)
		{
			return new NotImplementedException($"Algorithm {LL.Algorithm} not implemented for {action}");
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public unsafe static int LZ4_decompress_safe(byte* source, byte* target, int sourceLength, int targetLength)
		{
			return LL.Algorithm switch
			{
				Algorithm.X64 => LL64.LZ4_decompress_safe(source, target, sourceLength, targetLength), 
				Algorithm.X32 => LL32.LZ4_decompress_safe(source, target, sourceLength, targetLength), 
				_ => throw AlgorithmNotImplemented("LZ4_decompress_safe"), 
			};
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public unsafe static int LZ4_decompress_safe_partial(byte* source, byte* target, int sourceLength, int targetLength)
		{
			return LL.Algorithm switch
			{
				Algorithm.X64 => LL64.LZ4_decompress_safe_partial(source, target, sourceLength, targetLength, targetLength), 
				Algorithm.X32 => LL32.LZ4_decompress_safe_partial(source, target, sourceLength, targetLength, targetLength), 
				_ => throw AlgorithmNotImplemented("LZ4_decompress_safe_partial"), 
			};
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public unsafe static int LZ4_decompress_safe_usingDict(byte* source, byte* target, int sourceLength, int targetLength, byte* dictionary, int dictionaryLength)
		{
			return LL.Algorithm switch
			{
				Algorithm.X64 => LL64.LZ4_decompress_safe_usingDict(source, target, sourceLength, targetLength, dictionary, dictionaryLength), 
				Algorithm.X32 => LL32.LZ4_decompress_safe_usingDict(source, target, sourceLength, targetLength, dictionary, dictionaryLength), 
				_ => throw AlgorithmNotImplemented("LZ4_decompress_safe_usingDict"), 
			};
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public unsafe static int LZ4_decompress_safe_continue(LL.LZ4_streamDecode_t* context, byte* source, byte* target, int sourceLength, int targetLength)
		{
			return LL.Algorithm switch
			{
				Algorithm.X64 => LL64.LZ4_decompress_safe_continue(context, source, target, sourceLength, targetLength), 
				Algorithm.X32 => LL32.LZ4_decompress_safe_continue(context, source, target, sourceLength, targetLength), 
				_ => throw AlgorithmNotImplemented("LZ4_decompress_safe_continue"), 
			};
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public unsafe static int LZ4_compress_fast(byte* source, byte* target, int sourceLength, int targetLength, int acceleration)
		{
			return LL.Algorithm switch
			{
				Algorithm.X64 => LL64.LZ4_compress_fast(source, target, sourceLength, targetLength, acceleration), 
				Algorithm.X32 => LL32.LZ4_compress_fast(source, target, sourceLength, targetLength, acceleration), 
				_ => throw AlgorithmNotImplemented("LZ4_compress_fast"), 
			};
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public unsafe static int LZ4_compress_fast_continue(LL.LZ4_stream_t* context, byte* source, byte* target, int sourceLength, int targetLength, int acceleration)
		{
			return LL.Algorithm switch
			{
				Algorithm.X64 => LL64.LZ4_compress_fast_continue(context, source, target, sourceLength, targetLength, acceleration), 
				Algorithm.X32 => LL32.LZ4_compress_fast_continue(context, source, target, sourceLength, targetLength, acceleration), 
				_ => throw AlgorithmNotImplemented("LZ4_compress_fast_continue"), 
			};
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public unsafe static int LZ4_compress_HC(byte* source, byte* target, int sourceLength, int targetLength, int level)
		{
			return LL.Algorithm switch
			{
				Algorithm.X64 => LL64.LZ4_compress_HC(source, target, sourceLength, targetLength, level), 
				Algorithm.X32 => LL32.LZ4_compress_HC(source, target, sourceLength, targetLength, level), 
				_ => throw AlgorithmNotImplemented("LZ4_compress_HC"), 
			};
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public unsafe static int LZ4_compress_HC_continue(LL.LZ4_streamHC_t* context, byte* source, byte* target, int sourceLength, int targetLength)
		{
			return LL.Algorithm switch
			{
				Algorithm.X64 => LL64.LZ4_compress_HC_continue(context, source, target, sourceLength, targetLength), 
				Algorithm.X32 => LL32.LZ4_compress_HC_continue(context, source, target, sourceLength, targetLength), 
				_ => throw AlgorithmNotImplemented("LZ4_compress_HC_continue"), 
			};
		}
	}
	public static class Pubternal
	{
		public class FastContext : UnmanagedResources
		{
			internal unsafe LL.LZ4_stream_t* Context { get; }

			public unsafe FastContext()
			{
				Context = (LL.LZ4_stream_t*)Mem.AllocZero(sizeof(LL.LZ4_stream_t));
			}

			protected unsafe override void ReleaseUnmanaged()
			{
				Mem.Free(Context);
			}
		}

		public unsafe static int CompressFast(FastContext context, byte* source, byte* target, int sourceLength, int targetLength, int acceleration)
		{
			return LLxx.LZ4_compress_fast_continue(context.Context, source, target, sourceLength, targetLength, acceleration);
		}
	}
	internal class LL32 : LL
	{
		protected static cParams_t[] clTable = new cParams_t[13]
		{
			new cParams_t(lz4hc_strat_e.lz4hc, 2u, 16u),
			new cParams_t(lz4hc_strat_e.lz4hc, 2u, 16u),
			new cParams_t(lz4hc_strat_e.lz4hc, 2u, 16u),
			new cParams_t(lz4hc_strat_e.lz4hc, 4u, 16u),
			new cParams_t(lz4hc_strat_e.lz4hc, 8u, 16u),
			new cParams_t(lz4hc_strat_e.lz4hc, 16u, 16u),
			new cParams_t(lz4hc_strat_e.lz4hc, 32u, 16u),
			new cParams_t(lz4hc_strat_e.lz4hc, 64u, 16u),
			new cParams_t(lz4hc_strat_e.lz4hc, 128u, 16u),
			new cParams_t(lz4hc_strat_e.lz4hc, 256u, 16u),
			new cParams_t(lz4hc_strat_e.lz4opt, 96u, 64u),
			new cParams_t(lz4hc_strat_e.lz4opt, 512u, 128u),
			new cParams_t(lz4hc_strat_e.lz4opt, 16384u, 4096u)
		};

		protected const int ALGORITHM_ARCH = 4;

		private static readonly uint[] _DeBruijnBytePos = new uint[32]
		{
			0u, 0u, 3u, 0u, 3u, 1u, 3u, 0u, 3u, 2u,
			2u, 1u, 3u, 2u, 0u, 1u, 3u, 3u, 1u, 2u,
			2u, 2u, 2u, 0u, 3u, 1u, 2u, 0u, 1u, 0u,
			1u, 1u
		};

		private unsafe static readonly uint* DeBruijnBytePos = Mem.CloneArray(_DeBruijnBytePos);

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static int LZ4_decompress_generic(byte* src, byte* dst, int srcSize, int outputSize, endCondition_directive endOnInput, earlyEnd_directive partialDecoding, dict_directive dict, byte* lowPrefix, byte* dictStart, uint dictSize)
		{
			return LZ4_decompress_generic(src, dst, srcSize, outputSize, endOnInput == endCondition_directive.endOnInputSize, partialDecoding == earlyEnd_directive.partial, dict, lowPrefix, dictStart, dictSize);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static int LZ4_decompress_generic(byte* src, byte* dst, int srcSize, int outputSize, bool endOnInput, bool partialDecoding, dict_directive dict, byte* lowPrefix, byte* dictStart, uint dictSize)
		{
			if (src == null)
			{
				return -1;
			}
			byte* ptr = src;
			byte* ptr2 = ptr + srcSize;
			byte* ptr3 = dst;
			byte* ptr4 = ptr3 + outputSize;
			byte* ptr5 = ((dictStart == null) ? null : (dictStart + dictSize));
			bool flag = endOnInput;
			bool flag2 = flag && dictSize < 65536;
			byte* ptr6 = ptr2 - (endOnInput ? 14 : 8) - 2;
			byte* ptr7 = ptr4 - (endOnInput ? 14 : 8) - 18;
			if (endOnInput && outputSize == 0)
			{
				if (partialDecoding)
				{
					return 0;
				}
				if (srcSize != 1 || *ptr != 0)
				{
					return -1;
				}
				return 0;
			}
			if (!endOnInput && outputSize == 0)
			{
				if (*ptr != 0)
				{
					return -1;
				}
				return 1;
			}
			if (endOnInput && srcSize == 0)
			{
				return -1;
			}
			while (true)
			{
				uint num = *(ptr++);
				uint num2 = num >> 4;
				uint num3;
				byte* ptr9;
				byte* ptr8;
				if ((endOnInput ? (num2 != 15) : (num2 <= 8)) && (!endOnInput || ptr < ptr6) && ptr3 <= ptr7)
				{
					if (endOnInput)
					{
						Mem32.Copy16(ptr3, ptr);
					}
					else
					{
						Mem.Copy8(ptr3, ptr);
					}
					ptr3 += num2;
					ptr += num2;
					num2 = num & 0xFu;
					num3 = Mem.Peek2(ptr);
					ptr += 2;
					ptr8 = ptr3 - num3;
					if (num2 != 15 && num3 >= 8 && (dict == dict_directive.withPrefix64k || ptr8 >= lowPrefix))
					{
						Mem32.Copy18(ptr3, ptr8);
						ptr3 += num2 + 4;
						continue;
					}
				}
				else
				{
					if (num2 == 15)
					{
						variable_length_error variable_length_error = variable_length_error.ok;
						num2 += LL.LZ4_readVLE(&ptr, ptr2 - 15, endOnInput, endOnInput, &variable_length_error);
						if (variable_length_error == variable_length_error.initial_error || (flag && ptr3 + num2 < ptr3) || (flag && ptr + num2 < ptr))
						{
							break;
						}
					}
					ptr9 = ptr3 + num2;
					if ((endOnInput && (ptr9 > ptr4 - 12 || ptr + num2 > ptr2 - 8)) || (!endOnInput && ptr9 > ptr4 - 8))
					{
						if (partialDecoding)
						{
							if (ptr + num2 > ptr2 - 8 && ptr + num2 != ptr2)
							{
								break;
							}
							if (ptr9 > ptr4)
							{
								ptr9 = ptr4;
								num2 = (uint)(ptr4 - ptr3);
							}
						}
						else if ((!endOnInput && ptr9 != ptr4) || (endOnInput && (ptr + num2 != ptr2 || ptr9 > ptr4)))
						{
							break;
						}
						Mem.Move(ptr3, ptr, (int)num2);
						ptr += num2;
						ptr3 += num2;
						if (!partialDecoding || ptr9 == ptr4 || ptr == ptr2)
						{
							goto IL_04a7;
						}
					}
					else
					{
						Mem32.WildCopy8(ptr3, ptr, ptr9);
						ptr += num2;
						ptr3 = ptr9;
					}
					num3 = Mem.Peek2(ptr);
					ptr += 2;
					ptr8 = ptr3 - num3;
					num2 = num & 0xFu;
				}
				if (num2 == 15)
				{
					variable_length_error variable_length_error2 = variable_length_error.ok;
					num2 += LL.LZ4_readVLE(&ptr, ptr2 - 5 + 1, endOnInput, initial_check: false, &variable_length_error2);
					if (variable_length_error2 != 0 || (flag && ptr3 + num2 < ptr3))
					{
						break;
					}
				}
				num2 += 4;
				if (flag2 && ptr8 + dictSize < lowPrefix)
				{
					break;
				}
				if (dict == dict_directive.usingExtDict && ptr8 < lowPrefix)
				{
					if (ptr3 + num2 > ptr4 - 5)
					{
						if (!partialDecoding)
						{
							break;
						}
						num2 = LL.MIN(num2, (uint)(ptr4 - ptr3));
					}
					if (num2 <= (uint)(lowPrefix - ptr8))
					{
						Mem.Move(ptr3, ptr5 - (lowPrefix - ptr8), (int)num2);
						ptr3 += num2;
						continue;
					}
					uint num4 = (uint)(lowPrefix - ptr8);
					uint num5 = num2 - num4;
					Mem.Copy(ptr3, ptr5 - num4, (int)num4);
					ptr3 += num4;
					if (num5 > (uint)(ptr3 - lowPrefix))
					{
						byte* ptr10 = ptr3 + num5;
						byte* ptr11 = lowPrefix;
						while (ptr3 < ptr10)
						{
							*(ptr3++) = *(ptr11++);
						}
					}
					else
					{
						Mem.Copy(ptr3, lowPrefix, (int)num5);
						ptr3 += num5;
					}
					continue;
				}
				ptr9 = ptr3 + num2;
				if (partialDecoding && ptr9 > ptr4 - 12)
				{
					uint num6 = LL.MIN(num2, (uint)(ptr4 - ptr3));
					byte* num7 = ptr8 + num6;
					byte* ptr12 = ptr3 + num6;
					if (num7 > ptr3)
					{
						while (ptr3 < ptr12)
						{
							*(ptr3++) = *(ptr8++);
						}
					}
					else
					{
						Mem.Copy(ptr3, ptr8, (int)num6);
					}
					ptr3 = ptr12;
					if (ptr3 != ptr4)
					{
						continue;
					}
					goto IL_04a7;
				}
				if (num3 < 8)
				{
					*ptr3 = *ptr8;
					ptr3[1] = ptr8[1];
					ptr3[2] = ptr8[2];
					ptr3[3] = ptr8[3];
					ptr8 += LL.inc32table[num3];
					Mem.Copy4(ptr3 + 4, ptr8);
					ptr8 -= LL.dec64table[num3];
				}
				else
				{
					Mem.Copy8(ptr3, ptr8);
					ptr8 += 8;
				}
				ptr3 += 8;
				if (ptr9 > ptr4 - 12)
				{
					byte* ptr13 = ptr4 - 7;
					if (ptr9 > ptr4 - 5)
					{
						break;
					}
					if (ptr3 < ptr13)
					{
						Mem32.WildCopy8(ptr3, ptr8, ptr13);
						ptr8 += ptr13 - ptr3;
						ptr3 = ptr13;
					}
					while (ptr3 < ptr9)
					{
						*(ptr3++) = *(ptr8++);
					}
				}
				else
				{
					Mem.Copy8(ptr3, ptr8);
					if (num2 > 16)
					{
						Mem32.WildCopy8(ptr3 + 8, ptr8 + 8, ptr9);
					}
				}
				ptr3 = ptr9;
				continue;
				IL_04a7:
				if (endOnInput)
				{
					return (int)(ptr3 - dst);
				}
				return (int)(ptr - src);
			}
			return (int)(-(ptr - src)) - 1;
		}

		public unsafe static int LZ4_decompress_safe(byte* source, byte* dest, int compressedSize, int maxDecompressedSize)
		{
			return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endCondition_directive.endOnInputSize, earlyEnd_directive.full, dict_directive.noDict, dest, null, 0u);
		}

		public unsafe static int LZ4_decompress_safe_withPrefix64k(byte* source, byte* dest, int compressedSize, int maxOutputSize)
		{
			return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endCondition_directive.endOnInputSize, earlyEnd_directive.full, dict_directive.withPrefix64k, dest - 65536, null, 0u);
		}

		public unsafe static int LZ4_decompress_safe_withSmallPrefix(byte* source, byte* dest, int compressedSize, int maxOutputSize, uint prefixSize)
		{
			return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endCondition_directive.endOnInputSize, earlyEnd_directive.full, dict_directive.noDict, dest - prefixSize, null, 0u);
		}

		public unsafe static int LZ4_decompress_safe_doubleDict(byte* source, byte* dest, int compressedSize, int maxOutputSize, uint prefixSize, void* dictStart, uint dictSize)
		{
			return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endCondition_directive.endOnInputSize, earlyEnd_directive.full, dict_directive.usingExtDict, dest - prefixSize, (byte*)dictStart, dictSize);
		}

		public unsafe static int LZ4_decompress_safe_forceExtDict(byte* source, byte* dest, int compressedSize, int maxOutputSize, void* dictStart, uint dictSize)
		{
			return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endCondition_directive.endOnInputSize, earlyEnd_directive.full, dict_directive.usingExtDict, dest, (byte*)dictStart, dictSize);
		}

		public unsafe static int LZ4_decompress_safe_usingDict(byte* source, byte* dest, int compressedSize, int maxOutputSize, byte* dictStart, int dictSize)
		{
			if (dictSize == 0)
			{
				return LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize);
			}
			if (dictStart + dictSize == dest)
			{
				if (dictSize >= 65535)
				{
					return LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize);
				}
				return LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, (uint)dictSize);
			}
			return LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, dictStart, (uint)dictSize);
		}

		public unsafe static int LZ4_decompress_safe_partial(byte* src, byte* dst, int compressedSize, int targetOutputSize, int dstCapacity)
		{
			uint outputSize = LL.MIN((uint)targetOutputSize, (uint)dstCapacity);
			return LZ4_decompress_generic(src, dst, compressedSize, (int)outputSize, endCondition_directive.endOnInputSize, earlyEnd_directive.partial, dict_directive.noDict, dst, null, 0u);
		}

		public unsafe static int LZ4_decompress_safe_continue(LZ4_streamDecode_t* LZ4_streamDecode, byte* source, byte* dest, int compressedSize, int maxOutputSize)
		{
			int num;
			if (LZ4_streamDecode->prefixSize == 0)
			{
				num = LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize);
				if (num <= 0)
				{
					return num;
				}
				LZ4_streamDecode->prefixSize = (uint)num;
				LZ4_streamDecode->prefixEnd = dest + num;
			}
			else if (LZ4_streamDecode->prefixEnd == dest)
			{
				num = ((LZ4_streamDecode->prefixSize >= 65535) ? LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize) : ((LZ4_streamDecode->extDictSize != 0) ? LZ4_decompress_safe_doubleDict(source, dest, compressedSize, maxOutputSize, LZ4_streamDecode->prefixSize, LZ4_streamDecode->externalDict, LZ4_streamDecode->extDictSize) : LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, LZ4_streamDecode->prefixSize)));
				if (num <= 0)
				{
					return num;
				}
				LZ4_streamDecode->prefixSize += (uint)num;
				LZ4_streamDecode->prefixEnd += num;
			}
			else
			{
				LZ4_streamDecode->extDictSize = LZ4_streamDecode->prefixSize;
				LZ4_streamDecode->externalDict = LZ4_streamDecode->prefixEnd - LZ4_streamDecode->extDictSize;
				num = LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, LZ4_streamDecode->externalDict, LZ4_streamDecode->extDictSize);
				if (num <= 0)
				{
					return num;
				}
				LZ4_streamDecode->prefixSize = (uint)num;
				LZ4_streamDecode->prefixEnd = dest + num;
			}
			return num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		protected unsafe static int LZ4_compress_generic(LZ4_stream_t* cctx, byte* source, byte* dest, int inputSize, int* inputConsumed, int maxOutputSize, limitedOutput_directive outputDirective, tableType_t tableType, dict_directive dictDirective, dictIssue_directive dictIssue, int acceleration)
		{
			byte* ptr = source;
			uint currentOffset = cctx->currentOffset;
			byte* ptr2 = source - currentOffset;
			LZ4_stream_t* dictCtx = cctx->dictCtx;
			byte* ptr3 = ((dictDirective == dict_directive.usingDictCtx) ? dictCtx->dictionary : cctx->dictionary);
			uint num = ((dictDirective == dict_directive.usingDictCtx) ? dictCtx->dictSize : cctx->dictSize);
			uint num2 = ((dictDirective == dict_directive.usingDictCtx) ? (currentOffset - dictCtx->currentOffset) : 0u);
			bool flag = dictDirective == dict_directive.usingExtDict || dictDirective == dict_directive.usingDictCtx;
			uint num3 = currentOffset - num;
			byte* ptr4 = ptr3 + num;
			byte* ptr5 = source;
			byte* ptr6 = ptr + inputSize;
			byte* ptr7 = ptr6 - 12 + 1;
			byte* ptr8 = ptr6 - 5;
			byte* ptr9 = ((dictDirective == dict_directive.usingDictCtx) ? (ptr3 + num - dictCtx->currentOffset) : (ptr3 + num - currentOffset));
			byte* ptr10 = dest;
			byte* ptr11 = ptr10 + maxOutputSize;
			uint num4 = 0u;
			if (outputDirective == limitedOutput_directive.fillOutput && maxOutputSize < 1)
			{
				return 0;
			}
			if ((uint)inputSize > 2113929216u)
			{
				return 0;
			}
			if (tableType == tableType_t.byU16 && inputSize >= 65547)
			{
				return 0;
			}
			_ = 1;
			byte* ptr12 = source - ((dictDirective == dict_directive.withPrefix64k) ? num : 0);
			if (dictDirective == dict_directive.usingDictCtx)
			{
				cctx->dictCtx = null;
				cctx->dictSize = (uint)inputSize;
			}
			else
			{
				cctx->dictSize += (uint)inputSize;
			}
			cctx->currentOffset += (uint)inputSize;
			cctx->tableType = tableType;
			if (inputSize >= 13)
			{
				LZ4_putPosition(ptr, cctx->hashTable, tableType, ptr2);
				ptr++;
				uint num5 = LZ4_hashPosition(ptr, tableType);
				while (true)
				{
					byte* ptr14;
					if (tableType == tableType_t.byPtr)
					{
						byte* ptr13 = ptr;
						int num6 = 1;
						int num7 = acceleration << 6;
						while (true)
						{
							uint h = num5;
							ptr = ptr13;
							ptr13 += num6;
							num6 = num7++ >> 6;
							if (ptr13 > ptr7)
							{
								break;
							}
							ptr14 = LL.LZ4_getPositionOnHash(h, cctx->hashTable, tableType, ptr2);
							num5 = LZ4_hashPosition(ptr13, tableType);
							LL.LZ4_putPositionOnHash(ptr, h, cctx->hashTable, tableType, ptr2);
							if (ptr14 + 65535 < ptr || Mem.Peek4(ptr14) != Mem.Peek4(ptr))
							{
								continue;
							}
							goto IL_02f6;
						}
						break;
					}
					byte* ptr15 = ptr;
					int num8 = 1;
					int num9 = acceleration << 6;
					uint num10;
					uint num11;
					while (true)
					{
						uint h2 = num5;
						num10 = (uint)(ptr15 - ptr2);
						num11 = LL.LZ4_getIndexOnHash(h2, cctx->hashTable, tableType);
						ptr = ptr15;
						ptr15 += num8;
						num8 = num9++ >> 6;
						if (ptr15 > ptr7)
						{
							break;
						}
						switch (dictDirective)
						{
						case dict_directive.usingDictCtx:
							if (num11 < currentOffset)
							{
								num11 = LL.LZ4_getIndexOnHash(h2, dictCtx->hashTable, tableType_t.byU32);
								ptr14 = ptr9 + num11;
								num11 += num2;
								ptr12 = ptr3;
							}
							else
							{
								ptr14 = ptr2 + num11;
								ptr12 = source;
							}
							break;
						case dict_directive.usingExtDict:
							if (num11 < currentOffset)
							{
								ptr14 = ptr9 + num11;
								ptr12 = ptr3;
							}
							else
							{
								ptr14 = ptr2 + num11;
								ptr12 = source;
							}
							break;
						default:
							ptr14 = ptr2 + num11;
							break;
						}
						num5 = LZ4_hashPosition(ptr15, tableType);
						LL.LZ4_putIndexOnHash(num10, h2, cctx->hashTable, tableType);
						if ((dictIssue == dictIssue_directive.dictSmall && num11 < num3) || (tableType != tableType_t.byU16 && num11 + 65535 < num10) || Mem.Peek4(ptr14) != Mem.Peek4(ptr))
						{
							continue;
						}
						goto IL_02eb;
					}
					break;
					IL_02f6:
					byte* ptr16 = ptr;
					while (ptr > ptr5 && ptr14 > ptr12 && ptr[-1] == ptr14[-1])
					{
						ptr--;
						ptr14--;
					}
					uint num12 = (uint)(ptr - ptr5);
					byte* ptr17 = ptr10++;
					if (outputDirective == limitedOutput_directive.limitedOutput && ptr10 + num12 + 8 + num12 / 255 > ptr11)
					{
						return 0;
					}
					if (outputDirective == limitedOutput_directive.fillOutput && ptr10 + (num12 + 240) / 255 + num12 + 2 + 1 + 12 - 4 > ptr11)
					{
						ptr10--;
						break;
					}
					if (num12 >= 15)
					{
						int num13 = (int)(num12 - 15);
						*ptr17 = 240;
						while (num13 >= 255)
						{
							*(ptr10++) = byte.MaxValue;
							num13 -= 255;
						}
						*(ptr10++) = (byte)num13;
					}
					else
					{
						*ptr17 = (byte)(num12 << 4);
					}
					Mem32.WildCopy8(ptr10, ptr5, ptr10 + num12);
					ptr10 += num12;
					while (true)
					{
						if (outputDirective == limitedOutput_directive.fillOutput && ptr10 + 2 + 1 + 12 - 4 > ptr11)
						{
							ptr10 = ptr17;
							break;
						}
						if (flag)
						{
							Mem.Poke2(ptr10, (ushort)num4);
							ptr10 += 2;
						}
						else
						{
							Mem.Poke2(ptr10, (ushort)(ptr - ptr14));
							ptr10 += 2;
						}
						uint num14;
						if ((dictDirective == dict_directive.usingExtDict || dictDirective == dict_directive.usingDictCtx) && ptr12 == ptr3)
						{
							byte* ptr18 = ptr + (ptr4 - ptr14);
							if (ptr18 > ptr8)
							{
								ptr18 = ptr8;
							}
							num14 = LZ4_count(ptr + 4, ptr14 + 4, ptr18);
							ptr += num14 + 4;
							if (ptr == ptr18)
							{
								uint num15 = LZ4_count(ptr18, source, ptr8);
								num14 += num15;
								ptr += num15;
							}
						}
						else
						{
							num14 = LZ4_count(ptr + 4, ptr14 + 4, ptr8);
							ptr += num14 + 4;
						}
						if (outputDirective != 0 && ptr10 + 6 + (num14 + 240) / 255 > ptr11)
						{
							if (outputDirective != limitedOutput_directive.fillOutput)
							{
								return 0;
							}
							uint num16 = (uint)(14 + ((int)(ptr11 - ptr10) - 1 - 5) * 255);
							ptr -= num14 - num16;
							num14 = num16;
							if (ptr <= ptr16)
							{
								for (byte* ptr19 = ptr; ptr19 <= ptr16; ptr19++)
								{
									LL.LZ4_clearHash(LZ4_hashPosition(ptr19, tableType), cctx->hashTable, tableType);
								}
							}
						}
						if (num14 >= 15)
						{
							byte* intPtr = ptr17;
							*intPtr += 15;
							num14 -= 15;
							Mem.Poke4(ptr10, uint.MaxValue);
							while (num14 >= 1020)
							{
								ptr10 += 4;
								Mem.Poke4(ptr10, uint.MaxValue);
								num14 -= 1020;
							}
							ptr10 += num14 / 255;
							*(ptr10++) = (byte)(num14 % 255);
						}
						else
						{
							byte* intPtr2 = ptr17;
							*intPtr2 += (byte)num14;
						}
						ptr5 = ptr;
						if (ptr >= ptr7)
						{
							break;
						}
						LZ4_putPosition(ptr - 2, cctx->hashTable, tableType, ptr2);
						if (tableType == tableType_t.byPtr)
						{
							ptr14 = LZ4_getPosition(ptr, cctx->hashTable, tableType, ptr2);
							LZ4_putPosition(ptr, cctx->hashTable, tableType, ptr2);
							if (ptr14 + 65535 >= ptr && Mem.Peek4(ptr14) == Mem.Peek4(ptr))
							{
								ptr17 = ptr10++;
								*ptr17 = 0;
								continue;
							}
						}
						else
						{
							uint h3 = LZ4_hashPosition(ptr, tableType);
							uint num17 = (uint)(ptr - ptr2);
							uint num18 = LL.LZ4_getIndexOnHash(h3, cctx->hashTable, tableType);
							switch (dictDirective)
							{
							case dict_directive.usingDictCtx:
								if (num18 < currentOffset)
								{
									num18 = LL.LZ4_getIndexOnHash(h3, dictCtx->hashTable, tableType_t.byU32);
									ptr14 = ptr9 + num18;
									ptr12 = ptr3;
									num18 += num2;
								}
								else
								{
									ptr14 = ptr2 + num18;
									ptr12 = source;
								}
								break;
							case dict_directive.usingExtDict:
								if (num18 < currentOffset)
								{
									ptr14 = ptr9 + num18;
									ptr12 = ptr3;
								}
								else
								{
									ptr14 = ptr2 + num18;
									ptr12 = source;
								}
								break;
							default:
								ptr14 = ptr2 + num18;
								break;
							}
							LL.LZ4_putIndexOnHash(num17, h3, cctx->hashTable, tableType);
							if ((dictIssue != dictIssue_directive.dictSmall || num18 >= num3) && (tableType == tableType_t.byU16 || num18 + 65535 >= num17) && Mem.Peek4(ptr14) == Mem.Peek4(ptr))
							{
								ptr17 = ptr10++;
								*ptr17 = 0;
								if (flag)
								{
									num4 = num17 - num18;
								}
								continue;
							}
						}
						goto IL_0703;
					}
					break;
					IL_0703:
					num5 = LZ4_hashPosition(++ptr, tableType);
					continue;
					IL_02eb:
					if (flag)
					{
						num4 = num10 - num11;
					}
					goto IL_02f6;
				}
			}
			uint num19 = (uint)(ptr6 - ptr5);
			if (outputDirective != 0 && ptr10 + num19 + 1 + (num19 + 255 - 15) / 255 > ptr11)
			{
				if (outputDirective != limitedOutput_directive.fillOutput)
				{
					return 0;
				}
				num19 = (uint)((int)(ptr11 - ptr10) - 1);
				num19 -= (num19 + 240) / 255;
			}
			if (num19 >= 15)
			{
				uint num20 = num19 - 15;
				*(ptr10++) = 240;
				while (num20 >= 255)
				{
					*(ptr10++) = byte.MaxValue;
					num20 -= 255;
				}
				*(ptr10++) = (byte)num20;
			}
			else
			{
				*(ptr10++) = (byte)(num19 << 4);
			}
			Mem.Copy(ptr10, ptr5, (int)num19);
			ptr = ptr5 + num19;
			ptr10 += num19;
			if (outputDirective == limitedOutput_directive.fillOutput)
			{
				*inputConsumed = (int)(ptr - source);
			}
			return (int)(ptr10 - dest);
		}

		public unsafe static int LZ4_compress_fast_extState(LZ4_stream_t* state, byte* source, byte* dest, int inputSize, int maxOutputSize, int acceleration)
		{
			LZ4_stream_t* cctx = LL.LZ4_initStream(state);
			if (acceleration < 1)
			{
				acceleration = 1;
			}
			if (maxOutputSize >= LL.LZ4_compressBound(inputSize))
			{
				if (inputSize < 65547)
				{
					return LZ4_compress_generic(cctx, source, dest, inputSize, null, 0, limitedOutput_directive.notLimited, tableType_t.byU16, dict_directive.noDict, dictIssue_directive.noDictIssue, acceleration);
				}
				tableType_t tableType = ((sizeof(void*) < 8 && (nuint)source > (nuint)65535u) ? tableType_t.byPtr : tableType_t.byU32);
				return LZ4_compress_generic(cctx, source, dest, inputSize, null, 0, limitedOutput_directive.notLimited, tableType, dict_directive.noDict, dictIssue_directive.noDictIssue, acceleration);
			}
			if (inputSize < 65547)
			{
				return LZ4_compress_generic(cctx, source, dest, inputSize, null, maxOutputSize, limitedOutput_directive.limitedOutput, tableType_t.byU16, dict_directive.noDict, dictIssue_directive.noDictIssue, acceleration);
			}
			tableType_t tableType2 = ((sizeof(void*) < 8 && (nuint)source > (nuint)65535u) ? tableType_t.byPtr : tableType_t.byU32);
			return LZ4_compress_generic(cctx, source, dest, inputSize, null, maxOutputSize, limitedOutput_directive.limitedOutput, tableType2, dict_directive.noDict, dictIssue_directive.noDictIssue, acceleration);
		}

		public unsafe static int LZ4_compress_fast(byte* source, byte* dest, int inputSize, int maxOutputSize, int acceleration)
		{
			LZ4_stream_t lZ4_stream_t = default(LZ4_stream_t);
			return LZ4_compress_fast_extState(&lZ4_stream_t, source, dest, inputSize, maxOutputSize, acceleration);
		}

		public unsafe static int LZ4_compress_default(byte* src, byte* dst, int srcSize, int maxOutputSize)
		{
			return LZ4_compress_fast(src, dst, srcSize, maxOutputSize, 1);
		}

		public unsafe static int LZ4_compress_fast_continue(LZ4_stream_t* LZ4_stream, byte* source, byte* dest, int inputSize, int maxOutputSize, int acceleration)
		{
			byte* ptr = LZ4_stream->dictionary + LZ4_stream->dictSize;
			if (LZ4_stream->dirty)
			{
				return 0;
			}
			LZ4_renormDictT(LZ4_stream, inputSize);
			if (acceleration < 1)
			{
				acceleration = 1;
			}
			if (LZ4_stream->dictSize - 1 < 3 && ptr != source)
			{
				LZ4_stream->dictSize = 0u;
				LZ4_stream->dictionary = source;
				ptr = source;
			}
			byte* ptr2 = source + inputSize;
			if (ptr2 > LZ4_stream->dictionary && ptr2 < ptr)
			{
				LZ4_stream->dictSize = (uint)(ptr - ptr2);
				if (LZ4_stream->dictSize > 65536)
				{
					LZ4_stream->dictSize = 65536u;
				}
				if (LZ4_stream->dictSize < 4)
				{
					LZ4_stream->dictSize = 0u;
				}
				LZ4_stream->dictionary = ptr - LZ4_stream->dictSize;
			}
			if (ptr == source)
			{
				if (LZ4_stream->dictSize < 65536 && LZ4_stream->dictSize < LZ4_stream->currentOffset)
				{
					return LZ4_compress_generic(LZ4_stream, source, dest, inputSize, null, maxOutputSize, limitedOutput_directive.limitedOutput, tableType_t.byU32, dict_directive.withPrefix64k, dictIssue_directive.dictSmall, acceleration);
				}
				return LZ4_compress_generic(LZ4_stream, source, dest, inputSize, null, maxOutputSize, limitedOutput_directive.limitedOutput, tableType_t.byU32, dict_directive.withPrefix64k, dictIssue_directive.noDictIssue, acceleration);
			}
			int result;
			if (LZ4_stream->dictCtx == null)
			{
				result = ((LZ4_stream->dictSize >= 65536 || LZ4_stream->dictSize >= LZ4_stream->currentOffset) ? LZ4_compress_generic(LZ4_stream, source, dest, inputSize, null, maxOutputSize, limitedOutput_directive.limitedOutput, tableType_t.byU32, dict_directive.usingExtDict, dictIssue_directive.noDictIssue, acceleration) : LZ4_compress_generic(LZ4_stream, source, dest, inputSize, null, maxOutputSize, limitedOutput_directive.limitedOutput, tableType_t.byU32, dict_directive.usingExtDict, dictIssue_directive.dictSmall, acceleration));
			}
			else if (inputSize > 4096)
			{
				Mem.Copy((byte*)LZ4_stream, (byte*)LZ4_stream->dictCtx, sizeof(LZ4_stream_t));
				result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, null, maxOutputSize, limitedOutput_directive.limitedOutput, tableType_t.byU32, dict_directive.usingExtDict, dictIssue_directive.noDictIssue, acceleration);
			}
			else
			{
				result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, null, maxOutputSize, limitedOutput_directive.limitedOutput, tableType_t.byU32, dict_directive.usingDictCtx, dictIssue_directive.noDictIssue, acceleration);
			}
			LZ4_stream->dictionary = source;
			LZ4_stream->dictSize = (uint)inputSize;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static uint LZ4HC_countPattern(byte* ip, byte* iEnd, uint pattern32)
		{
			byte* ptr = ip;
			while (ip < iEnd - 3)
			{
				uint num = Mem32.PeekW(ip) ^ pattern32;
				if (num == 0)
				{
					ip += 4;
					continue;
				}
				ip += LZ4_NbCommonBytes(num);
				return (uint)(ip - ptr);
			}
			uint num2 = pattern32;
			while (ip < iEnd && *ip == (byte)num2)
			{
				ip++;
				num2 >>= 8;
			}
			return (uint)(ip - ptr);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static int LZ4HC_InsertAndGetWiderMatch(LZ4_streamHC_t* hc4, byte* ip, byte* iLowLimit, byte* iHighLimit, int longest, byte** matchpos, byte** startpos, int maxNbAttempts, bool patternAnalysis, bool chainSwap, dictCtx_directive dict, HCfavor_e favorDecSpeed)
		{
			ushort* table = hc4->chainTable;
			uint* num = hc4->hashTable;
			LZ4_streamHC_t* dictCtx = hc4->dictCtx;
			byte* @base = hc4->@base;
			uint dictLimit = hc4->dictLimit;
			byte* ptr = @base + dictLimit;
			uint num2 = (uint)(ip - @base);
			uint num3 = ((hc4->lowLimit + 65536 > num2) ? hc4->lowLimit : (num2 - 65535));
			byte* dictBase = hc4->dictBase;
			int num4 = (int)(ip - iLowLimit);
			int num5 = maxNbAttempts;
			uint num6 = 0u;
			uint num7 = Mem.Peek4(ip);
			repeat_state_e repeat_state_e = repeat_state_e.rep_untested;
			uint num8 = 0u;
			LL.LZ4HC_Insert(hc4, ip);
			uint num9 = num[LL.LZ4HC_hashPtr(ip)];
			while (num9 >= num3 && num5 != 0)
			{
				int num10 = 0;
				num5--;
				if (favorDecSpeed == HCfavor_e.favorCompressionRatio || num2 - num9 >= 8)
				{
					if (num9 >= dictLimit)
					{
						byte* ptr2 = @base + num9;
						if (Mem.Peek2(iLowLimit + longest - 1) == Mem.Peek2(ptr2 - num4 + longest - 1) && Mem.Peek4(ptr2) == num7)
						{
							int num11 = ((num4 != 0) ? LL.LZ4HC_countBack(ip, ptr2, iLowLimit, ptr) : 0);
							num10 = (int)(4 + LZ4_count(ip + 4, ptr2 + 4, iHighLimit));
							num10 -= num11;
							if (num10 > longest)
							{
								longest = num10;
								*matchpos = ptr2 + num11;
								*startpos = ip + num11;
							}
						}
					}
					else
					{
						byte* ptr3 = dictBase + num9;
						if (Mem.Peek4(ptr3) == num7)
						{
							byte* mMin = dictBase + hc4->lowLimit;
							int num12 = 0;
							byte* ptr4 = ip + (dictLimit - num9);
							if (ptr4 > iHighLimit)
							{
								ptr4 = iHighLimit;
							}
							num10 = (int)(LZ4_count(ip + 4, ptr3 + 4, ptr4) + 4);
							if (ip + num10 == ptr4 && ptr4 < iHighLimit)
							{
								num10 += (int)LZ4_count(ip + num10, ptr, iHighLimit);
							}
							num12 = ((num4 != 0) ? LL.LZ4HC_countBack(ip, ptr3, iLowLimit, mMin) : 0);
							num10 -= num12;
							if (num10 > longest)
							{
								longest = num10;
								*matchpos = @base + num9 + num12;
								*startpos = ip + num12;
							}
						}
					}
				}
				if (chainSwap && num10 == longest && (uint)((int)num9 + longest) <= num2)
				{
					int num13 = 4;
					uint num14 = 1u;
					int num15 = longest - 4 + 1;
					int num16 = 1;
					int num17 = 1 << num13;
					for (int i = 0; i < num15; i += num16)
					{
						uint num18 = LL.DELTANEXTU16(table, num9 + (uint)i);
						num16 = num17++ >> num13;
						if (num18 > num14)
						{
							num14 = num18;
							num6 = (uint)i;
							num17 = 1 << num13;
						}
					}
					if (num14 > 1)
					{
						if (num14 > num9)
						{
							break;
						}
						num9 -= num14;
						continue;
					}
				}
				uint num19 = LL.DELTANEXTU16(table, num9);
				if (patternAnalysis && num19 == 1 && num6 == 0)
				{
					uint num20 = num9 - 1;
					if (repeat_state_e == repeat_state_e.rep_untested)
					{
						if ((num7 & 0xFFFF) == num7 >> 16 && (num7 & 0xFF) == num7 >> 24)
						{
							repeat_state_e = repeat_state_e.rep_confirmed;
							num8 = LZ4HC_countPattern(ip + 4, iHighLimit, num7) + 4;
						}
						else
						{
							repeat_state_e = repeat_state_e.rep_not;
						}
					}
					if (repeat_state_e == repeat_state_e.rep_confirmed && num20 >= num3 && LL.LZ4HC_protectDictEnd(dictLimit, num20))
					{
						bool flag = num20 < dictLimit;
						byte* ptr5 = (flag ? dictBase : @base) + num20;
						if (Mem.Peek4(ptr5) == num7)
						{
							byte* ptr6 = dictBase + hc4->lowLimit;
							byte* ptr7 = (flag ? (dictBase + dictLimit) : iHighLimit);
							uint num21 = LZ4HC_countPattern(ptr5 + 4, ptr7, num7) + 4;
							if (flag && ptr5 + num21 == ptr7)
							{
								uint pattern = LL.LZ4HC_rotatePattern(num21, num7);
								num21 += LZ4HC_countPattern(ptr, iHighLimit, pattern);
							}
							byte* iLow = (flag ? ptr6 : ptr);
							uint num22 = LL.LZ4HC_reverseCountPattern(ptr5, iLow, num7);
							if (!flag && ptr5 - num22 == ptr && hc4->lowLimit < dictLimit)
							{
								uint pattern2 = LL.LZ4HC_rotatePattern(0 - num22, num7);
								num22 += LL.LZ4HC_reverseCountPattern(dictBase + dictLimit, ptr6, pattern2);
							}
							num22 = num20 - LL.MAX(num20 - num22, num3);
							uint num23 = num22 + num21;
							if (num23 >= num8 && num21 <= num8)
							{
								uint num24 = num20 + num21 - num8;
								num9 = ((!LL.LZ4HC_protectDictEnd(dictLimit, num24)) ? dictLimit : num24);
								continue;
							}
							uint num25 = num20 - num22;
							if (!LL.LZ4HC_protectDictEnd(dictLimit, num25))
							{
								num9 = dictLimit;
								continue;
							}
							num9 = num25;
							if (num4 != 0)
							{
								continue;
							}
							uint num26 = LL.MIN(num23, num8);
							if ((uint)longest < num26)
							{
								if ((uint)((int)(ip - @base) - (int)num9) > 65535u)
								{
									break;
								}
								longest = (int)num26;
								*matchpos = @base + num9;
								*startpos = ip;
							}
							uint num27 = LL.DELTANEXTU16(table, num9);
							if (num27 > num9)
							{
								break;
							}
							num9 -= num27;
							continue;
						}
					}
				}
				num9 -= LL.DELTANEXTU16(table, num9 + num6);
			}
			if (dict == dictCtx_directive.usingDictCtxHc && num5 != 0 && num2 - num3 < 65535)
			{
				uint num28 = (uint)(dictCtx->end - dictCtx->@base);
				uint num29 = dictCtx->hashTable[LL.LZ4HC_hashPtr(ip)];
				num9 = num29 + num3 - num28;
				while (num2 - num9 <= 65535 && num5-- != 0)
				{
					byte* ptr8 = dictCtx->@base + num29;
					if (Mem.Peek4(ptr8) == num7)
					{
						int num30 = 0;
						byte* ptr9 = ip + (num28 - num29);
						if (ptr9 > iHighLimit)
						{
							ptr9 = iHighLimit;
						}
						int num31 = (int)(LZ4_count(ip + 4, ptr8 + 4, ptr9) + 4);
						num30 = ((num4 != 0) ? LL.LZ4HC_countBack(ip, ptr8, iLowLimit, dictCtx->@base + dictCtx->dictLimit) : 0);
						num31 -= num30;
						if (num31 > longest)
						{
							longest = num31;
							*matchpos = @base + num9 + num30;
							*startpos = ip + num30;
						}
					}
					uint num32 = LL.DELTANEXTU16(dictCtx->chainTable, num29);
					num29 -= num32;
					num9 -= num32;
				}
			}
			return longest;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static int LZ4HC_InsertAndFindBestMatch(LZ4_streamHC_t* hc4, byte* ip, byte* iLimit, byte** matchpos, int maxNbAttempts, bool patternAnalysis, dictCtx_directive dict)
		{
			byte* ptr = ip;
			return LZ4HC_InsertAndGetWiderMatch(hc4, ip, ip, iLimit, 3, matchpos, &ptr, maxNbAttempts, patternAnalysis, chainSwap: false, dict, HCfavor_e.favorCompressionRatio);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static LZ4HC_match_t LZ4HC_FindLongerMatch(LZ4_streamHC_t* ctx, byte* ip, byte* iHighLimit, int minLen, int nbSearches, dictCtx_directive dict, HCfavor_e favorDecSpeed)
		{
			LZ4HC_match_t result = default(LZ4HC_match_t);
			result.len = 0;
			result.off = 0;
			byte* ptr = null;
			int num = LZ4HC_InsertAndGetWiderMatch(ctx, ip, ip, iHighLimit, minLen, &ptr, &ip, nbSearches, patternAnalysis: true, chainSwap: true, dict, favorDecSpeed);
			if (num <= minLen)
			{
				return result;
			}
			if (favorDecSpeed != 0 && num > 18 && num <= 36)
			{
				num = 18;
			}
			result.len = num;
			result.off = (int)(ip - ptr);
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static int LZ4HC_encodeSequence(byte** ip, byte** op, byte** anchor, int matchLength, byte* match, limitedOutput_directive limit, byte* oend)
		{
			byte* ptr = (*op)++;
			uint num = (uint)(*ip - *anchor);
			if (limit != 0 && *op + num / 255 + num + 8 > oend)
			{
				return 1;
			}
			if (num >= 15)
			{
				uint num2 = num - 15;
				*ptr = 240;
				while (num2 >= 255)
				{
					*((*op)++) = byte.MaxValue;
					num2 -= 255;
				}
				*((*op)++) = (byte)num2;
			}
			else
			{
				*ptr = (byte)(num << 4);
			}
			Mem32.WildCopy8(*op, *anchor, *op + num);
			*op += num;
			Mem.Poke2(*op, (ushort)(*ip - match));
			*op += 2;
			num = (uint)(matchLength - 4);
			if (limit != 0 && *op + num / 255 + 6 > oend)
			{
				return 1;
			}
			if (num >= 15)
			{
				*ptr += 15;
				for (num -= 15; num >= 510; num -= 510)
				{
					*((*op)++) = byte.MaxValue;
					*((*op)++) = byte.MaxValue;
				}
				if (num >= 255)
				{
					num -= 255;
					*((*op)++) = byte.MaxValue;
				}
				*((*op)++) = (byte)num;
			}
			else
			{
				*ptr += (byte)num;
			}
			*ip += matchLength;
			*anchor = *ip;
			return 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static int LZ4HC_compress_hashChain(LZ4_streamHC_t* ctx, byte* source, byte* dest, int* srcSizePtr, int maxOutputSize, int maxNbAttempts, limitedOutput_directive limit, dictCtx_directive dict)
		{
			int num = *srcSizePtr;
			bool patternAnalysis = maxNbAttempts > 128;
			byte* ptr = source;
			byte* ptr2 = ptr;
			byte* ptr3 = ptr + num;
			byte* ptr4 = ptr3 - 12;
			byte* ptr5 = ptr3 - 5;
			byte* ptr6 = dest;
			byte* ptr7 = dest;
			byte* ptr8 = ptr7 + maxOutputSize;
			byte* ptr9 = null;
			byte* ptr10 = null;
			byte* ptr11 = null;
			byte* ptr12 = null;
			byte* ptr13 = null;
			*srcSizePtr = 0;
			if (limit == limitedOutput_directive.fillOutput)
			{
				ptr8 -= 5;
			}
			if (num >= 13)
			{
				while (ptr <= ptr4)
				{
					int num2 = LZ4HC_InsertAndFindBestMatch(ctx, ptr, ptr5, &ptr9, maxNbAttempts, patternAnalysis, dict);
					if (num2 < 4)
					{
						ptr++;
						continue;
					}
					byte* ptr14 = ptr;
					byte* ptr15 = ptr9;
					int num3 = num2;
					while (true)
					{
						int num4 = ((ptr + num2 > ptr4) ? num2 : LZ4HC_InsertAndGetWiderMatch(ctx, ptr + num2 - 2, ptr, ptr5, num2, &ptr11, &ptr10, maxNbAttempts, patternAnalysis, chainSwap: false, dict, HCfavor_e.favorCompressionRatio));
						int num7;
						if (num4 == num2)
						{
							ptr6 = ptr7;
							if (LZ4HC_encodeSequence(&ptr, &ptr7, &ptr2, num2, ptr9, limit, ptr8) == 0)
							{
								break;
							}
						}
						else
						{
							if (ptr14 < ptr && ptr10 < ptr + num3)
							{
								ptr = ptr14;
								ptr9 = ptr15;
								num2 = num3;
							}
							if (ptr10 - ptr < 3)
							{
								num2 = num4;
								ptr = ptr10;
								ptr9 = ptr11;
								continue;
							}
							while (true)
							{
								if (ptr10 - ptr < 18)
								{
									int num5 = num2;
									if (num5 > 18)
									{
										num5 = 18;
									}
									if (ptr + num5 > ptr10 + num4 - 4)
									{
										num5 = (int)(ptr10 - ptr) + num4 - 4;
									}
									int num6 = num5 - (int)(ptr10 - ptr);
									if (num6 > 0)
									{
										ptr10 += num6;
										ptr11 += num6;
										num4 -= num6;
									}
								}
								num7 = ((ptr10 + num4 > ptr4) ? num4 : LZ4HC_InsertAndGetWiderMatch(ctx, ptr10 + num4 - 3, ptr10, ptr5, num4, &ptr13, &ptr12,

K4os.Compression.LZ4.Streams.dll

Decompiled 2 weeks ago
using System;
using System.Buffers;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.IO.Pipelines;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Threading.Tasks;
using K4os.Compression.LZ4.Encoders;
using K4os.Compression.LZ4.Internal;
using K4os.Compression.LZ4.Streams.Abstractions;
using K4os.Compression.LZ4.Streams.Adapters;
using K4os.Compression.LZ4.Streams.Frames;
using K4os.Compression.LZ4.Streams.Internal;
using K4os.Hash.xxHash;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("Milosz Krajewski")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Milosz Krajewski")]
[assembly: AssemblyDescription("Port of LZ4 compression algorithm for .NET")]
[assembly: AssemblyFileVersion("1.3.8.0")]
[assembly: AssemblyInformationalVersion("1.3.8")]
[assembly: AssemblyProduct("K4os.Compression.LZ4")]
[assembly: AssemblyTitle("K4os.Compression.LZ4.Streams")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MiloszKrajewski/K4os.Compression.LZ4")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.8.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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;
		}
	}
}
namespace System
{
	[ExcludeFromCodeCoverage]
	internal readonly struct Index : IEquatable<Index>
	{
		private static class ThrowHelper
		{
			[DoesNotReturn]
			public static void ThrowValueArgumentOutOfRange_NeedNonNegNumException()
			{
				throw new ArgumentOutOfRangeException("value", "Non-negative number required.");
			}
		}

		private readonly int _value;

		public static Index Start => new Index(0);

		public static Index End => new Index(-1);

		public int Value
		{
			get
			{
				if (_value < 0)
				{
					return ~_value;
				}
				return _value;
			}
		}

		public bool IsFromEnd => _value < 0;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Index(int value, bool fromEnd = false)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			if (fromEnd)
			{
				_value = ~value;
			}
			else
			{
				_value = value;
			}
		}

		private Index(int value)
		{
			_value = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Index FromStart(int value)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			return new Index(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Index FromEnd(int value)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			return new Index(~value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int GetOffset(int length)
		{
			int num = _value;
			if (IsFromEnd)
			{
				num += length + 1;
			}
			return num;
		}

		public override bool Equals([NotNullWhen(true)] object? value)
		{
			if (value is Index)
			{
				return _value == ((Index)value)._value;
			}
			return false;
		}

		public bool Equals(Index other)
		{
			return _value == other._value;
		}

		public override int GetHashCode()
		{
			return _value;
		}

		public static implicit operator Index(int value)
		{
			return FromStart(value);
		}

		public override string ToString()
		{
			if (IsFromEnd)
			{
				return ToStringFromEnd();
			}
			return ((uint)Value).ToString();
		}

		private string ToStringFromEnd()
		{
			return "^" + Value;
		}
	}
}
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.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[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.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : 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
	{
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class DisallowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public MaybeNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[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.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class NotNullIfNotNullAttribute : Attribute
	{
		public string ParameterName { get; }

		public NotNullIfNotNullAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[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 K4os.Compression.LZ4.Streams
{
	public static class Extensions
	{
		internal static ReadOnlySpan<T> AsReadOnly<T>(this Span<T> span)
		{
			return span;
		}

		internal static ReadOnlyMemory<T> AsReadOnly<T>(this Memory<T> memory)
		{
			return memory;
		}

		private static int ExtraBlocks(int blockSize, int extraMemory)
		{
			return Math.Max((extraMemory > 0) ? blockSize : 0, extraMemory) / blockSize;
		}

		public static ILZ4Encoder CreateEncoder(this ILZ4Descriptor descriptor, LZ4Level level = 0, int extraMemory = 0)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return LZ4Encoder.Create(descriptor.Chaining, level, descriptor.BlockSize, ExtraBlocks(descriptor.BlockSize, extraMemory));
		}

		public static ILZ4Encoder CreateEncoder(this ILZ4Descriptor descriptor, LZ4EncoderSettings settings)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return LZ4Encoder.Create(descriptor.Chaining, settings.CompressionLevel, descriptor.BlockSize, ExtraBlocks(descriptor.BlockSize, settings.ExtraMemory));
		}

		public static ILZ4Decoder CreateDecoder(this ILZ4Descriptor descriptor, int extraMemory = 0)
		{
			return LZ4Decoder.Create(descriptor.Chaining, descriptor.BlockSize, ExtraBlocks(descriptor.BlockSize, extraMemory));
		}

		public static ILZ4Decoder CreateDecoder(this ILZ4Descriptor descriptor, LZ4DecoderSettings settings)
		{
			return LZ4Decoder.Create(descriptor.Chaining, descriptor.BlockSize, ExtraBlocks(descriptor.BlockSize, settings.ExtraMemory));
		}

		public static ILZ4Descriptor CreateDescriptor(this LZ4EncoderSettings settings)
		{
			return new LZ4Descriptor(settings.ContentLength, settings.ContentChecksum, settings.ChainBlocks, settings.BlockChecksum, settings.Dictionary, settings.BlockSize);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Task<bool> OpenFrameAsync(this ILZ4FrameReader reader)
		{
			return reader.OpenFrameAsync(CancellationToken.None);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Task<long?> GetFrameLengthAsync(this ILZ4FrameReader reader)
		{
			return reader.GetFrameLengthAsync(CancellationToken.None);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Task<int> ReadOneByteAsync(this ILZ4FrameReader reader)
		{
			return reader.ReadOneByteAsync(CancellationToken.None);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Task<int> ReadManyBytesAsync(this ILZ4FrameReader reader, Memory<byte> buffer, bool interactive = false)
		{
			return reader.ReadManyBytesAsync(CancellationToken.None, buffer, interactive);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Task<bool> OpenFrameAsync(this ILZ4FrameWriter writer)
		{
			return writer.OpenFrameAsync(CancellationToken.None);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Task WriteOneByteAsync(this ILZ4FrameWriter writer, byte value)
		{
			return writer.WriteOneByteAsync(CancellationToken.None, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Task WriteManyBytesAsync(this ILZ4FrameWriter writer, ReadOnlyMemory<byte> buffer)
		{
			return writer.WriteManyBytesAsync(CancellationToken.None, buffer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Task CloseFrameAsync(this ILZ4FrameWriter writer)
		{
			return writer.CloseFrameAsync(CancellationToken.None);
		}

		public static void CopyTo<TBufferWriter>(this ILZ4FrameReader source, TBufferWriter target, int blockSize = 0) where TBufferWriter : IBufferWriter<byte>
		{
			blockSize = Math.Max(blockSize, 4096);
			while (true)
			{
				Span<byte> span = ((IBufferWriter<byte>)target).GetSpan(blockSize);
				int num = source.ReadManyBytes(span, interactive: true);
				if (num == 0)
				{
					break;
				}
				((IBufferWriter<byte>)target).Advance(num);
			}
		}

		public static async Task CopyToAsync<TBufferWriter>(this ILZ4FrameReader source, TBufferWriter target, int blockSize = 0) where TBufferWriter : IBufferWriter<byte>
		{
			blockSize = Math.Max(blockSize, 4096);
			while (true)
			{
				Memory<byte> memory = ((IBufferWriter<byte>)target).GetMemory(blockSize);
				int num = await source.ReadManyBytesAsync(memory, interactive: true).Weave();
				if (num == 0)
				{
					break;
				}
				((IBufferWriter<byte>)target).Advance(num);
			}
		}

		public static int CopyFrom(this ILZ4FrameWriter target, ReadOnlySequence<byte> source)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			while (!source.IsEmpty)
			{
				ReadOnlyMemory<byte> first = source.First;
				int length = first.Length;
				num += length;
				source = source.Slice((long)length);
				if (!first.IsEmpty)
				{
					target.WriteManyBytes(first.Span);
				}
			}
			return num;
		}

		public static async Task<int> CopyFromAsync(this ILZ4FrameWriter target, ReadOnlySequence<byte> source)
		{
			//IL_0016: 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)
			int total = 0;
			while (!source.IsEmpty)
			{
				ReadOnlyMemory<byte> first = source.First;
				int length = first.Length;
				total += length;
				source = source.Slice((long)length);
				if (!first.IsEmpty)
				{
					await target.WriteManyBytesAsync(first).Weave();
				}
			}
			return total;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static LZ4FrameReaderAsStream AsStream(this ILZ4FrameReader reader, bool leaveOpen = false, bool interactive = false)
		{
			return new LZ4FrameReaderAsStream(reader, leaveOpen, interactive);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static LZ4FrameWriterAsStream AsStream(this ILZ4FrameWriter writer, bool leaveOpen = false)
		{
			return new LZ4FrameWriterAsStream(writer, leaveOpen);
		}
	}
	public interface ILZ4Descriptor
	{
		long? ContentLength { get; }

		bool ContentChecksum { get; }

		bool Chaining { get; }

		bool BlockChecksum { get; }

		uint? Dictionary { get; }

		int BlockSize { get; }
	}
	public class LZ4DecoderSettings
	{
		internal static LZ4DecoderSettings Default { get; } = new LZ4DecoderSettings();


		public int ExtraMemory { get; set; }
	}
	public class LZ4DecoderStream : LZ4StreamOnStreamEssentials
	{
		private readonly StreamLZ4FrameReader _reader;

		private readonly bool _interactive;

		public override bool CanWrite => false;

		public override long Length => _reader.GetFrameLength() ?? (-1);

		public override long Position => _reader.GetBytesRead();

		public LZ4DecoderStream(Stream inner, Func<ILZ4Descriptor, ILZ4Decoder> decoderFactory, bool leaveOpen = false, bool interactive = false)
			: base(inner, leaveOpen)
		{
			_reader = new StreamLZ4FrameReader(inner, leaveOpen: true, decoderFactory);
			_interactive = interactive;
		}

		public override int ReadByte()
		{
			return _reader.ReadOneByte();
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			return _reader.ReadManyBytes(buffer.AsSpan(offset, count), _interactive);
		}

		public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken token)
		{
			return _reader.ReadManyBytesAsync(token, buffer.AsMemory(offset, count), _interactive);
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				_reader.Dispose();
			}
			base.Dispose(disposing);
		}
	}
	public class LZ4Descriptor : ILZ4Descriptor
	{
		public long? ContentLength { get; }

		public bool ContentChecksum { get; }

		public bool Chaining { get; }

		public bool BlockChecksum { get; }

		public uint? Dictionary { get; }

		public int BlockSize { get; }

		public LZ4Descriptor(long? contentLength, bool contentChecksum, bool chaining, bool blockChecksum, uint? dictionary, int blockSize)
		{
			ContentLength = contentLength;
			ContentChecksum = contentChecksum;
			Chaining = chaining;
			BlockChecksum = blockChecksum;
			Dictionary = dictionary;
			BlockSize = blockSize;
		}

		public LZ4Descriptor(ILZ4Descriptor descriptor)
		{
			ContentLength = descriptor.ContentLength;
			ContentChecksum = descriptor.ContentChecksum;
			Chaining = descriptor.Chaining;
			BlockChecksum = descriptor.BlockChecksum;
			Dictionary = descriptor.Dictionary;
			BlockSize = descriptor.BlockSize;
		}
	}
	public class LZ4EncoderSettings
	{
		internal static LZ4EncoderSettings Default { get; } = new LZ4EncoderSettings();


		public long? ContentLength { get; set; }

		public bool ChainBlocks { get; set; } = true;


		public int BlockSize { get; set; } = 65536;


		public bool ContentChecksum { get; set; }

		public bool BlockChecksum { get; set; }

		public uint? Dictionary => null;

		public LZ4Level CompressionLevel { get; set; }

		public int ExtraMemory { get; set; }
	}
	public class LZ4EncoderStream : LZ4StreamOnStreamEssentials
	{
		private readonly StreamLZ4FrameWriter _writer;

		public override bool CanRead => false;

		public override long Length => _writer.GetBytesWritten();

		public override long Position => _writer.GetBytesWritten();

		public LZ4EncoderStream(Stream inner, ILZ4Descriptor descriptor, Func<ILZ4Descriptor, ILZ4Encoder> encoderFactory, bool leaveOpen = false)
			: base(inner, leaveOpen)
		{
			_writer = new StreamLZ4FrameWriter(inner, leaveOpen: true, encoderFactory, descriptor);
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				_writer.Dispose();
			}
			base.Dispose(disposing);
		}

		public override void WriteByte(byte value)
		{
			_writer.WriteOneByte(value);
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			_writer.WriteManyBytes(buffer.AsSpan(offset, count));
		}

		public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken token)
		{
			return _writer.WriteManyBytesAsync(token, buffer.AsMemory(offset, count));
		}
	}
	public static class LZ4Frame
	{
		public unsafe static TBufferWriter Decode<TBufferWriter>(ReadOnlySpan<byte> source, TBufferWriter target, int extraMemory = 0) where TBufferWriter : IBufferWriter<byte>
		{
			fixed (byte* bytes = source)
			{
				ByteSpanLZ4FrameReader byteSpanLZ4FrameReader = new ByteSpanLZ4FrameReader(UnsafeByteSpan.Create(bytes, source.Length), (ILZ4Descriptor i) => i.CreateDecoder(extraMemory));
				using (byteSpanLZ4FrameReader)
				{
					byteSpanLZ4FrameReader.CopyTo(target);
					return target;
				}
			}
		}

		public static ByteMemoryLZ4FrameReader Decode(ReadOnlyMemory<byte> memory, int extraMemory = 0)
		{
			return new ByteMemoryLZ4FrameReader(memory, (ILZ4Descriptor i) => i.CreateDecoder(extraMemory));
		}

		public static ByteSequenceLZ4FrameReader Decode(ReadOnlySequence<byte> sequence, int extraMemory = 0)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			return new ByteSequenceLZ4FrameReader(sequence, (ILZ4Descriptor i) => i.CreateDecoder(extraMemory));
		}

		public static StreamLZ4FrameReader Decode(Stream stream, int extraMemory = 0, bool leaveOpen = false)
		{
			return new StreamLZ4FrameReader(stream, leaveOpen, (ILZ4Descriptor i) => i.CreateDecoder(extraMemory));
		}

		public static PipeLZ4FrameReader Decode(PipeReader reader, int extraMemory = 0, bool leaveOpen = false)
		{
			return new PipeLZ4FrameReader(reader, leaveOpen, (ILZ4Descriptor i) => i.CreateDecoder(extraMemory));
		}

		private static LZ4EncoderSettings ToEncoderSettings(LZ4Level level, int extraMemory)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return new LZ4EncoderSettings
			{
				CompressionLevel = level,
				ExtraMemory = extraMemory
			};
		}

		public static TBufferWriter Encode<TBufferWriter>(ReadOnlySequence<byte> source, TBufferWriter target, LZ4EncoderSettings? settings = null) where TBufferWriter : IBufferWriter<byte>
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			ByteBufferLZ4FrameWriter<TBufferWriter> byteBufferLZ4FrameWriter = new ByteBufferLZ4FrameWriter<TBufferWriter>(target, (ILZ4Descriptor i) => i.CreateEncoder(settings2.CompressionLevel, settings2.ExtraMemory), settings2.CreateDescriptor());
			using (byteBufferLZ4FrameWriter)
			{
				byteBufferLZ4FrameWriter.CopyFrom(source);
			}
			return byteBufferLZ4FrameWriter.BufferWriter;
		}

		public static TBufferWriter Encode<TBufferWriter>(ReadOnlySpan<byte> source, TBufferWriter target, LZ4EncoderSettings? settings = null) where TBufferWriter : IBufferWriter<byte>
		{
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			ByteBufferLZ4FrameWriter<TBufferWriter> byteBufferLZ4FrameWriter = new ByteBufferLZ4FrameWriter<TBufferWriter>(target, (ILZ4Descriptor i) => i.CreateEncoder(settings2.CompressionLevel, settings2.ExtraMemory), settings2.CreateDescriptor());
			using (byteBufferLZ4FrameWriter)
			{
				byteBufferLZ4FrameWriter.WriteManyBytes(source);
			}
			return byteBufferLZ4FrameWriter.BufferWriter;
		}

		public static TBufferWriter Encode<TBufferWriter>(ReadOnlySequence<byte> source, TBufferWriter target, LZ4Level level, int extraMemory = 0) where TBufferWriter : IBufferWriter<byte>
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Encode(source, target, ToEncoderSettings(level, extraMemory));
		}

		public static TBufferWriter Encode<TBufferWriter>(ReadOnlySpan<byte> source, TBufferWriter target, LZ4Level level, int extraMemory = 0) where TBufferWriter : IBufferWriter<byte>
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Encode(source, target, ToEncoderSettings(level, extraMemory));
		}

		public unsafe static int Encode(ReadOnlySequence<byte> source, Span<byte> target, LZ4EncoderSettings? settings = null)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			fixed (byte* bytes = target)
			{
				ByteSpanLZ4FrameWriter byteSpanLZ4FrameWriter = new ByteSpanLZ4FrameWriter(UnsafeByteSpan.Create(bytes, target.Length), (ILZ4Descriptor i) => i.CreateEncoder(settings2.CompressionLevel, settings2.ExtraMemory), settings2.CreateDescriptor());
				using (byteSpanLZ4FrameWriter)
				{
					byteSpanLZ4FrameWriter.CopyFrom(source);
				}
				return byteSpanLZ4FrameWriter.CompressedLength;
			}
		}

		public unsafe static int Encode(Span<byte> source, Span<byte> target, LZ4EncoderSettings? settings = null)
		{
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			fixed (byte* bytes = target)
			{
				ByteSpanLZ4FrameWriter byteSpanLZ4FrameWriter = new ByteSpanLZ4FrameWriter(UnsafeByteSpan.Create(bytes, target.Length), (ILZ4Descriptor i) => i.CreateEncoder(settings2.CompressionLevel, settings2.ExtraMemory), settings2.CreateDescriptor());
				using (byteSpanLZ4FrameWriter)
				{
					byteSpanLZ4FrameWriter.WriteManyBytes(source);
				}
				return byteSpanLZ4FrameWriter.CompressedLength;
			}
		}

		public unsafe static int Encode(Action<ILZ4FrameWriter> source, Span<byte> target, LZ4EncoderSettings? settings = null)
		{
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			fixed (byte* bytes = target)
			{
				ByteSpanLZ4FrameWriter byteSpanLZ4FrameWriter = new ByteSpanLZ4FrameWriter(UnsafeByteSpan.Create(bytes, target.Length), (ILZ4Descriptor i) => i.CreateEncoder(settings2.CompressionLevel, settings2.ExtraMemory), settings2.CreateDescriptor());
				using (byteSpanLZ4FrameWriter)
				{
					source(byteSpanLZ4FrameWriter);
				}
				return byteSpanLZ4FrameWriter.CompressedLength;
			}
		}

		public static int Encode(ReadOnlySequence<byte> source, Span<byte> target, LZ4Level level, int extraMemory = 0)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Encode(source, target, ToEncoderSettings(level, extraMemory));
		}

		public static int Encode(Span<byte> source, Span<byte> target, LZ4Level level, int extraMemory = 0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Encode(source, target, ToEncoderSettings(level, extraMemory));
		}

		public static int Encode(Action<ILZ4FrameWriter> source, Span<byte> target, LZ4Level level, int extraMemory = 0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Encode(source, target, ToEncoderSettings(level, extraMemory));
		}

		public unsafe static ByteSpanLZ4FrameWriter Encode(byte* target, int length, LZ4EncoderSettings? settings = null)
		{
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			return new ByteSpanLZ4FrameWriter(UnsafeByteSpan.Create(target, length), (ILZ4Descriptor i) => i.CreateEncoder(settings2.CompressionLevel, settings2.ExtraMemory), settings2.CreateDescriptor());
		}

		public unsafe static ByteSpanLZ4FrameWriter Encode(byte* target, int length, LZ4Level level, int extraMemory = 0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Encode(target, length, ToEncoderSettings(level, extraMemory));
		}

		public static ByteMemoryLZ4FrameWriter Encode(Memory<byte> target, LZ4EncoderSettings? settings = null)
		{
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			return new ByteMemoryLZ4FrameWriter(target, (ILZ4Descriptor i) => i.CreateEncoder(settings2.CompressionLevel, settings2.ExtraMemory), settings2.CreateDescriptor());
		}

		public static ByteMemoryLZ4FrameWriter Encode(Memory<byte> target, LZ4Level level, int extraMemory = 0)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Encode(target, ToEncoderSettings(level, extraMemory));
		}

		public static ByteBufferLZ4FrameWriter<TBufferWriter> Encode<TBufferWriter>(TBufferWriter target, LZ4EncoderSettings? settings = null) where TBufferWriter : IBufferWriter<byte>
		{
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			return new ByteBufferLZ4FrameWriter<TBufferWriter>(target, (ILZ4Descriptor i) => i.CreateEncoder(settings2.CompressionLevel, settings2.ExtraMemory), settings2.CreateDescriptor());
		}

		public static ByteBufferLZ4FrameWriter<TBufferWriter> Encode<TBufferWriter>(TBufferWriter target, LZ4Level level, int extraMemory = 0) where TBufferWriter : IBufferWriter<byte>
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Encode(target, ToEncoderSettings(level, extraMemory));
		}

		public static ByteBufferLZ4FrameWriter Encode(IBufferWriter<byte> target, LZ4EncoderSettings? settings = null)
		{
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			return new ByteBufferLZ4FrameWriter(target, (ILZ4Descriptor i) => i.CreateEncoder(settings2.CompressionLevel, settings2.ExtraMemory), settings2.CreateDescriptor());
		}

		public static ByteBufferLZ4FrameWriter Encode(IBufferWriter<byte> target, LZ4Level level, int extraMemory = 0)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Encode(target, ToEncoderSettings(level, extraMemory));
		}

		public static StreamLZ4FrameWriter Encode(Stream target, LZ4EncoderSettings? settings = null, bool leaveOpen = false)
		{
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			return new StreamLZ4FrameWriter(target, leaveOpen, (ILZ4Descriptor i) => i.CreateEncoder(settings2.CompressionLevel, settings2.ExtraMemory), settings2.CreateDescriptor());
		}

		public static StreamLZ4FrameWriter Encode(Stream target, LZ4Level level, int extraMemory = 0, bool leaveOpen = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Encode(target, ToEncoderSettings(level, extraMemory), leaveOpen);
		}

		public static PipeLZ4FrameWriter Encode(PipeWriter target, LZ4EncoderSettings? settings = null, bool leaveOpen = false)
		{
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			return new PipeLZ4FrameWriter(target, leaveOpen, (ILZ4Descriptor i) => i.CreateEncoder(settings2.CompressionLevel, settings2.ExtraMemory), settings2.CreateDescriptor());
		}

		public static PipeLZ4FrameWriter Encode(PipeWriter target, LZ4Level level, int extraMemory = 0, bool leaveOpen = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Encode(target, ToEncoderSettings(level, extraMemory), leaveOpen);
		}
	}
	public static class LZ4Stream
	{
		public static LZ4EncoderStream Encode(Stream stream, LZ4EncoderSettings? settings = null, bool leaveOpen = false)
		{
			LZ4EncoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4EncoderSettings.Default;
			}
			ILZ4Descriptor descriptor = settings2.CreateDescriptor();
			return new LZ4EncoderStream(stream, descriptor, (ILZ4Descriptor i) => i.CreateEncoder(settings2), leaveOpen);
		}

		public static LZ4EncoderStream Encode(Stream stream, LZ4Level level, int extraMemory = 0, bool leaveOpen = false)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			LZ4EncoderSettings settings = new LZ4EncoderSettings
			{
				ChainBlocks = true,
				ExtraMemory = extraMemory,
				BlockSize = 65536,
				CompressionLevel = level
			};
			return Encode(stream, settings, leaveOpen);
		}

		public static LZ4DecoderStream Decode(Stream stream, LZ4DecoderSettings? settings = null, bool leaveOpen = false, bool interactive = false)
		{
			LZ4DecoderSettings settings2 = settings;
			if (settings2 == null)
			{
				settings2 = LZ4DecoderSettings.Default;
			}
			return new LZ4DecoderStream(stream, (ILZ4Descriptor i) => i.CreateDecoder(settings2), leaveOpen, interactive);
		}

		public static LZ4DecoderStream Decode(Stream stream, int extraMemory, bool leaveOpen = false, bool interactive = false)
		{
			LZ4DecoderSettings settings = new LZ4DecoderSettings
			{
				ExtraMemory = extraMemory
			};
			return Decode(stream, settings, leaveOpen, interactive);
		}
	}
}
namespace K4os.Compression.LZ4.Streams.Internal
{
	internal readonly struct BlockInfo
	{
		private readonly byte[] _buffer;

		private readonly int _length;

		public byte[] Buffer => _buffer;

		public int Offset => 0;

		public int Length => Math.Abs(_length);

		public bool Compressed => _length > 0;

		public bool Ready => _length != 0;

		public BlockInfo(byte[] buffer, EncoderAction action, int length)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			_buffer = buffer;
			int length2 = (((int)action == 2) ? (-length) : (((int)action == 3) ? length : 0));
			_length = length2;
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal readonly struct EmptyToken
	{
		public static readonly EmptyToken Value;
	}
	internal static class Extensions
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ConfiguredTaskAwaitable<T> Weave<T>(this Task<T> task)
		{
			return task.ConfigureAwait(continueOnCapturedContext: false);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ConfiguredTaskAwaitable Weave(this Task task)
		{
			return task.ConfigureAwait(continueOnCapturedContext: false);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ConfiguredValueTaskAwaitable<T> Weave<T>(this ValueTask<T> task)
		{
			return task.ConfigureAwait(continueOnCapturedContext: false);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ConfiguredValueTaskAwaitable Weave(this ValueTask task)
		{
			return task.ConfigureAwait(continueOnCapturedContext: false);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<byte> ToSpan(this ReadOnlySpan<byte> span)
		{
			return span;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<byte> ToSpan(this ReadOnlyMemory<byte> span)
		{
			return span.Span;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<byte> ToSpan(this Span<byte> span)
		{
			return span;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<byte> ToSpan(this Memory<byte> span)
		{
			return span.Span;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[Conditional("DEBUG")]
		public static void AssertIsNotNull<T>([NotNull] this T? value, [CallerArgumentExpression("value")] string? name = null) where T : class
		{
			if (value == null)
			{
				ThrowArgumentNullException(name);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		[DoesNotReturn]
		private static void ThrowArgumentNullException(string? name)
		{
			throw new ArgumentNullException(name);
		}
	}
	public abstract class LZ4StreamEssentials<T> : Stream
	{
		private readonly T _innerResource;

		private readonly bool _doNotDispose;

		private bool _alreadyDisposed;

		protected T InnerResource => _innerResource;

		public override bool CanRead => false;

		public override bool CanWrite => false;

		public override bool CanTimeout => false;

		public override int ReadTimeout
		{
			get
			{
				throw NotImplemented("ReadTimeout");
			}
			set
			{
				throw NotImplemented("ReadTimeout");
			}
		}

		public override int WriteTimeout
		{
			get
			{
				throw NotImplemented("WriteTimeout");
			}
			set
			{
				throw NotImplemented("WriteTimeout");
			}
		}

		public override bool CanSeek => false;

		public override long Position
		{
			get
			{
				throw NotImplemented("GetPosition");
			}
			set
			{
				Seek(value, SeekOrigin.Begin);
			}
		}

		public override long Length
		{
			get
			{
				throw NotImplemented("GetLength");
			}
		}

		protected LZ4StreamEssentials(T innerResource, bool doNotDispose)
		{
			_innerResource = innerResource;
			_doNotDispose = doNotDispose;
		}

		private protected NotImplementedException NotImplemented(string operation)
		{
			return new NotImplementedException("Feature " + operation + " has not been implemented in " + GetType().Name);
		}

		private protected InvalidOperationException InvalidOperation(string operation)
		{
			return new InvalidOperationException("Operation " + operation + " is not allowed for " + GetType().Name);
		}

		private protected static ArgumentException InvalidValue(string description)
		{
			return new ArgumentException(description);
		}

		public override void Flush()
		{
		}

		public override Task FlushAsync(CancellationToken token)
		{
			return Task.CompletedTask;
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			throw InvalidOperation("Seek");
		}

		public override void SetLength(long value)
		{
			throw InvalidOperation("SetLength");
		}

		public override int ReadByte()
		{
			throw InvalidOperation("ReadByte");
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			throw InvalidOperation("Read");
		}

		public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken token)
		{
			throw InvalidOperation("ReadAsync");
		}

		protected override void Dispose(bool disposing)
		{
			if (ShouldDisposeInner(disposing))
			{
				if ((object)_innerResource is IDisposable disposable)
				{
					disposable.Dispose();
				}
				_alreadyDisposed = true;
			}
			base.Dispose(disposing);
		}

		public override void WriteByte(byte value)
		{
			throw InvalidOperation("WriteByte");
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			throw InvalidOperation("Write");
		}

		public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken token)
		{
			throw InvalidOperation("WriteAsync");
		}

		private bool ShouldDisposeInner(bool disposing = true)
		{
			if (disposing && !_doNotDispose)
			{
				return !_alreadyDisposed;
			}
			return false;
		}
	}
	public abstract class LZ4StreamOnStreamEssentials : LZ4StreamEssentials<Stream>
	{
		public override bool CanRead => base.InnerResource.CanRead;

		public override bool CanWrite => base.InnerResource.CanWrite;

		public override bool CanTimeout => base.InnerResource.CanTimeout;

		public override int ReadTimeout
		{
			get
			{
				return base.InnerResource.ReadTimeout;
			}
			set
			{
				base.InnerResource.ReadTimeout = value;
			}
		}

		public override int WriteTimeout
		{
			get
			{
				return base.InnerResource.WriteTimeout;
			}
			set
			{
				base.InnerResource.WriteTimeout = value;
			}
		}

		private protected LZ4StreamOnStreamEssentials(Stream innerStream, bool leaveOpen)
			: base(innerStream, leaveOpen)
		{
		}

		public override void Flush()
		{
			base.InnerResource.Flush();
		}

		public override Task FlushAsync(CancellationToken token)
		{
			return base.InnerResource.FlushAsync(token);
		}
	}
	internal static class ReaderExtensions
	{
		private static EndOfStreamException EndOfStream()
		{
			return new EndOfStreamException("Unexpected end of stream. Data might be corrupted.");
		}

		public static int TryReadBlock<TStreamReader, TStreamState>(this TStreamReader stream, ref TStreamState state, byte[] buffer, int offset, int count, bool optional) where TStreamReader : IStreamReader<TStreamState>
		{
			int num = 0;
			while (count > 0)
			{
				int num2 = stream.Read(ref state, buffer, offset + num, count);
				if (num2 == 0)
				{
					if (!(num == 0 && optional))
					{
						throw EndOfStream();
					}
					return 0;
				}
				num += num2;
				count -= num2;
			}
			return num;
		}

		public static async Task<ReadResult<TStreamState>> TryReadBlockAsync<TStreamReader, TStreamState>(this TStreamReader stream, TStreamState state, byte[] buffer, int offset, int count, bool optional, CancellationToken token) where TStreamReader : IStreamReader<TStreamState>
		{
			int progress = 0;
			while (count > 0)
			{
				int num2;
				(state, num2) = (ReadResult<TStreamState>)(ref await stream.ReadAsync(state, buffer, offset + progress, count, token).Weave());
				if (num2 == 0)
				{
					if (!(progress == 0 && optional))
					{
						throw EndOfStream();
					}
					return ReadResult.Create(state);
				}
				progress += num2;
				count -= num2;
			}
			return ReadResult.Create(state, progress);
		}
	}
	internal struct Stash
	{
		private byte[] _buffer;

		private readonly int _size;

		private int _head;

		public byte[] Data
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return _buffer;
			}
		}

		public int Head
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return _head;
			}
		}

		public Stash()
			: this(32)
		{
		}

		public Stash(int size)
		{
			_buffer = BufferPool.Alloc(size, false);
			_size = _buffer.Length - 8;
			_head = 0;
		}

		public void Dispose()
		{
			if (_buffer != null)
			{
				BufferPool.Free(_buffer);
			}
			_buffer = null;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int Flush()
		{
			int head = _head;
			_head = 0;
			return head;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int Advance(int loaded)
		{
			_head += loaded;
			return loaded;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<byte> AsSpan(int offset = 0)
		{
			return _buffer.AsSpan(offset, Math.Max(0, _head - offset));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public byte OneByteValue()
		{
			return _buffer[_size];
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<byte> OneByteSpan()
		{
			return _buffer.AsSpan(_size, 1);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<byte> OneByteSpan(byte value)
		{
			Span<byte> result = OneByteSpan();
			result[0] = value;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<byte> OneByteMemory()
		{
			return _buffer.AsMemory(_size, 1);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<byte> OneByteMemory(byte value)
		{
			Memory<byte> result = OneByteMemory();
			result.Span[0] = value;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<byte> OneByteBuffer(in EmptyToken _)
		{
			return OneByteSpan();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<byte> OneByteBuffer(in CancellationToken _)
		{
			return OneByteMemory();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ulong Last8(int loaded = 0)
		{
			return BitConverter.ToUInt64(_buffer, (_head += loaded) - 8);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public uint Last4(int loaded = 0)
		{
			return BitConverter.ToUInt32(_buffer, (_head += loaded) - 4);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ushort Last2(int loaded = 0)
		{
			return BitConverter.ToUInt16(_buffer, (_head += loaded) - 2);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public byte Last1(int loaded = 0)
		{
			return _buffer[(_head += loaded) - 1];
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Poke1(byte value)
		{
			PokeN(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Poke2(ushort value)
		{
			PokeN(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Poke4(uint value)
		{
			PokeN(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Poke8(ulong value)
		{
			PokeN(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void TryPoke4(uint? value)
		{
			if (value.HasValue)
			{
				Poke4(value.Value);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void ValidateBuffer()
		{
			if (_head >= _size)
			{
				throw new InvalidOperationException($"Buffer too small ({_size})");
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe void PokeN<T>(T value) where T : struct
		{
			ValidateBuffer();
			System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(ref _buffer[_head], ref *(byte*)System.Runtime.CompilerServices.Unsafe.AsPointer<T>(ref value), (uint)System.Runtime.CompilerServices.Unsafe.SizeOf<T>());
			_head += System.Runtime.CompilerServices.Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public uint Digest(int offset = 0)
		{
			return XXH32.DigestOf((ReadOnlySpan<byte>)AsSpan(offset));
		}
	}
}
namespace K4os.Compression.LZ4.Streams.Frames
{
	public class LZ4FrameReader<TStreamReader, TStreamState> : ILZ4FrameReader, IDisposable where TStreamReader : IStreamReader<TStreamState>
	{
		private readonly TStreamReader _reader;

		private TStreamState _stream;

		private Stash _stash = new Stash();

		private readonly Func<ILZ4Descriptor, ILZ4Decoder> _decoderFactory;

		private ILZ4Descriptor? _descriptor;

		private ILZ4Decoder? _decoder;

		private State _contentChecksum;

		private byte[]? _buffer;

		private int _decoded;

		private long _bytesRead;

		public TStreamState StreamState => _stream;

		private async Task<ulong> Peek8(CancellationToken token)
		{
			int loaded = await ReadMeta(token, 8).Weave();
			return _stash.Last8(loaded);
		}

		private async Task<uint?> TryPeek4(CancellationToken token)
		{
			int num = await ReadMeta(token, 4, optional: true).Weave();
			return (num <= 0) ? null : new uint?(_stash.Last4(num));
		}

		private async Task<uint> Peek4(CancellationToken token)
		{
			int loaded = await ReadMeta(token, 4).Weave();
			return _stash.Last4(loaded);
		}

		private async Task<ushort> Peek2(CancellationToken token)
		{
			int loaded = await ReadMeta(token, 2).Weave();
			return _stash.Last2(loaded);
		}

		private async Task<byte> Peek1(CancellationToken token)
		{
			int loaded = await ReadMeta(token, 1).Weave();
			return _stash.Last1(loaded);
		}

		private async Task<bool> EnsureHeader(CancellationToken token)
		{
			bool flag = _decoder != null;
			if (!flag)
			{
				flag = await ReadHeader(token).Weave();
			}
			return flag;
		}

		private async Task<bool> ReadHeader(CancellationToken token)
		{
			_stash.Flush();
			uint? num = await TryPeek4(token).Weave();
			if (!num.HasValue)
			{
				return false;
			}
			if (num != 407708164)
			{
				throw MagicNumberExpected();
			}
			int headerOffset = _stash.Head;
			ushort num2 = await Peek2(token).Weave();
			int num3 = num2 & 0xFF;
			int num4 = (num2 >> 8) & 0xFF;
			int num5 = (num3 >> 6) & 0x11;
			if (num5 != 1)
			{
				throw UnknownFrameVersion(num5);
			}
			bool blockChaining = ((num3 >> 5) & 1) == 0;
			bool blockChecksum = ((num3 >> 4) & 1) != 0;
			bool num6 = ((num3 >> 3) & 1) != 0;
			bool contentChecksum = ((num3 >> 2) & 1) != 0;
			bool hasDictionary = (num3 & 1) != 0;
			int blockSizeCode = (num4 >> 4) & 7;
			long? num7 = ((!num6) ? null : new long?((long)(await Peek8(token).Weave())));
			long? contentLength = num7;
			uint? num8 = ((!hasDictionary) ? null : new uint?(await Peek4(token).Weave()));
			uint? dictionaryId = num8;
			byte actualHC = (byte)(_stash.Digest(headerOffset) >> 8);
			if (actualHC != await Peek1(token).Weave())
			{
				throw InvalidHeaderChecksum();
			}
			int num9 = MaxBlockSize(blockSizeCode);
			if (hasDictionary)
			{
				throw NotImplemented("Predefined dictionaries feature is not implemented");
			}
			if (contentChecksum)
			{
				InitializeContentChecksum();
			}
			_descriptor = new LZ4Descriptor(contentLength, contentChecksum, blockChaining, blockChecksum, dictionaryId, num9);
			_decoder = CreateDecoder(_descriptor);
			_buffer = AllocBuffer(num9);
			return true;
		}

		private async Task<int> ReadBlock(CancellationToken token)
		{
			_stash.Flush();
			int blockLength = (int)(await Peek4(token).Weave());
			if (blockLength == 0)
			{
				if (_descriptor.ContentChecksum)
				{
					VerifyContentChecksum(await Peek4(token).Weave());
				}
				CloseFrame();
				return 0;
			}
			bool uncompressed = (blockLength & 0x80000000u) != 0;
			blockLength &= 0x7FFFFFFF;
			await ReadData(token, blockLength).Weave();
			if (_descriptor.BlockChecksum)
			{
				VerifyBlockChecksum(await Peek4(token).Weave(), blockLength);
			}
			int num = InjectOrDecode(blockLength, uncompressed);
			UpdateContentChecksum(num);
			return num;
		}

		private async Task<long?> GetFrameLength(CancellationToken token)
		{
			await EnsureHeader(token).Weave();
			return _descriptor?.ContentLength;
		}

		private async Task<int> ReadOneByte(CancellationToken token)
		{
			return (await ReadManyBytes(token, _stash.OneByteBuffer(in token)).Weave() > 0) ? _stash.OneByteValue() : (-1);
		}

		private async Task<int> ReadManyBytes(CancellationToken token, Memory<byte> buffer, bool interactive = false)
		{
			if (!(await EnsureHeader(token).Weave()))
			{
				return 0;
			}
			int offset = 0;
			int count = buffer.Length;
			int read = 0;
			while (count > 0)
			{
				bool flag = _decoded <= 0;
				if (flag)
				{
					flag = (_decoded = await ReadBlock(token).Weave()) == 0;
				}
				if (flag || Drain(buffer.ToSpan(), ref offset, ref count, ref read) || interactive)
				{
					break;
				}
			}
			return read;
		}

		private ulong Peek8(EmptyToken token)
		{
			int loaded = ReadMeta(token, 8);
			return _stash.Last8(loaded);
		}

		private uint? TryPeek4(EmptyToken token)
		{
			int num = ReadMeta(token, 4, optional: true);
			if (num > 0)
			{
				return _stash.Last4(num);
			}
			return null;
		}

		private uint Peek4(EmptyToken token)
		{
			int loaded = ReadMeta(token, 4);
			return _stash.Last4(loaded);
		}

		private ushort Peek2(EmptyToken token)
		{
			int loaded = ReadMeta(token, 2);
			return _stash.Last2(loaded);
		}

		private byte Peek1(EmptyToken token)
		{
			int loaded = ReadMeta(token, 1);
			return _stash.Last1(loaded);
		}

		private bool EnsureHeader(EmptyToken token)
		{
			if (_decoder == null)
			{
				return ReadHeader(token);
			}
			return true;
		}

		private bool ReadHeader(EmptyToken token)
		{
			_stash.Flush();
			uint? num = TryPeek4(token);
			if (!num.HasValue)
			{
				return false;
			}
			if (num != 407708164)
			{
				throw MagicNumberExpected();
			}
			int head = _stash.Head;
			ushort num2 = Peek2(token);
			int num3 = num2 & 0xFF;
			int num4 = (num2 >> 8) & 0xFF;
			int num5 = (num3 >> 6) & 0x11;
			if (num5 != 1)
			{
				throw UnknownFrameVersion(num5);
			}
			bool chaining = ((num3 >> 5) & 1) == 0;
			bool blockChecksum = ((num3 >> 4) & 1) != 0;
			bool flag = ((num3 >> 3) & 1) != 0;
			bool flag2 = ((num3 >> 2) & 1) != 0;
			bool num6 = (num3 & 1) != 0;
			int blockSizeCode = (num4 >> 4) & 7;
			long? contentLength = (flag ? new long?((long)Peek8(token)) : null);
			uint? dictionary = (num6 ? new uint?(Peek4(token)) : null);
			byte num7 = (byte)(_stash.Digest(head) >> 8);
			byte b = Peek1(token);
			if (num7 != b)
			{
				throw InvalidHeaderChecksum();
			}
			int num8 = MaxBlockSize(blockSizeCode);
			if (num6)
			{
				throw NotImplemented("Predefined dictionaries feature is not implemented");
			}
			if (flag2)
			{
				InitializeContentChecksum();
			}
			_descriptor = new LZ4Descriptor(contentLength, flag2, chaining, blockChecksum, dictionary, num8);
			_decoder = CreateDecoder(_descriptor);
			_buffer = AllocBuffer(num8);
			return true;
		}

		private int ReadBlock(EmptyToken token)
		{
			_stash.Flush();
			int num = (int)Peek4(token);
			if (num == 0)
			{
				if (_descriptor.ContentChecksum)
				{
					VerifyContentChecksum(Peek4(token));
				}
				CloseFrame();
				return 0;
			}
			bool uncompressed = (num & 0x80000000u) != 0;
			num &= 0x7FFFFFFF;
			ReadData(token, num);
			if (_descriptor.BlockChecksum)
			{
				VerifyBlockChecksum(Peek4(token), num);
			}
			int num2 = InjectOrDecode(num, uncompressed);
			UpdateContentChecksum(num2);
			return num2;
		}

		private long? GetFrameLength(EmptyToken token)
		{
			EnsureHeader(token);
			return _descriptor?.ContentLength;
		}

		private int ReadOneByte(EmptyToken token)
		{
			if (ReadManyBytes(token, _stash.OneByteBuffer(in token)) <= 0)
			{
				return -1;
			}
			return _stash.OneByteValue();
		}

		private int ReadManyBytes(EmptyToken token, Span<byte> buffer, bool interactive = false)
		{
			if (!EnsureHeader(token))
			{
				return 0;
			}
			int offset = 0;
			int count = buffer.Length;
			int read = 0;
			while (count > 0 && (_decoded > 0 || (_decoded = ReadBlock(token)) != 0) && !(Drain(buffer.ToSpan(), ref offset, ref count, ref read) || interactive))
			{
			}
			return read;
		}

		public LZ4FrameReader(TStreamReader reader, TStreamState stream, Func<ILZ4Descriptor, ILZ4Decoder> decoderFactory)
		{
			_decoderFactory = decoderFactory;
			_reader = reader;
			_stream = stream;
			_bytesRead = 0L;
		}

		private static int MaxBlockSize(int blockSizeCode)
		{
			return blockSizeCode switch
			{
				7 => 4194304, 
				6 => 1048576, 
				5 => 262144, 
				4 => 65536, 
				_ => 65536, 
			};
		}

		private ILZ4Decoder CreateDecoder(ILZ4Descriptor descriptor)
		{
			return _decoderFactory(descriptor);
		}

		public void CloseFrame()
		{
			if (_decoder == null)
			{
				return;
			}
			try
			{
				if (_buffer != null)
				{
					ReleaseBuffer(_buffer);
				}
				((IDisposable)_decoder).Dispose();
			}
			finally
			{
				_descriptor = null;
				_buffer = null;
				_decoder = null;
			}
		}

		protected virtual byte[] AllocBuffer(int size)
		{
			return BufferPool.Alloc(size, false);
		}

		protected virtual void ReleaseBuffer(byte[] buffer)
		{
			BufferPool.Free(buffer);
		}

		private int InjectOrDecode(int blockLength, bool uncompressed)
		{
			if (!uncompressed)
			{
				return LZ4EncoderExtensions.Decode(_decoder, _buffer, 0, blockLength, 0);
			}
			return LZ4EncoderExtensions.Inject(_decoder, _buffer, 0, blockLength);
		}

		private bool Drain(Span<byte> buffer, ref int offset, ref int count, ref int read)
		{
			if (_decoded <= 0)
			{
				return true;
			}
			int num = Math.Min(count, _decoded);
			LZ4EncoderExtensions.Drain(_decoder, buffer.Slice(offset), -_decoded, num);
			_bytesRead += num;
			_decoded -= num;
			offset += num;
			count -= num;
			read += num;
			return false;
		}

		private void VerifyBlockChecksum(uint expected, int blockLength)
		{
			if (XXH32.DigestOf(_buffer, 0, blockLength) != expected)
			{
				throw InvalidChecksum("block");
			}
		}

		private void InitializeContentChecksum()
		{
			XXH32.Reset(ref _contentChecksum, 0u);
		}

		private unsafe void UpdateContentChecksum(int read)
		{
			Span<byte> span = new Span<byte>(_decoder.Peek(-read), read);
			XXH32.Update(ref _contentChecksum, (ReadOnlySpan<byte>)span);
		}

		private void VerifyContentChecksum(uint expected)
		{
			uint num = XXH32.Digest(ref _contentChecksum);
			if (expected != num)
			{
				throw InvalidChecksum("content");
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool OpenFrame()
		{
			return EnsureHeader(EmptyToken.Value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Task<bool> OpenFrameAsync(CancellationToken token)
		{
			return EnsureHeader(token);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public long GetBytesRead()
		{
			return _bytesRead;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public long? GetFrameLength()
		{
			return GetFrameLength(EmptyToken.Value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Task<long?> GetFrameLengthAsync(CancellationToken token = default(CancellationToken))
		{
			return GetFrameLength(token);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int ReadOneByte()
		{
			return ReadOneByte(EmptyToken.Value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Task<int> ReadOneByteAsync(CancellationToken token = default(CancellationToken))
		{
			return ReadOneByte(token);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int ReadManyBytes(Span<byte> buffer, bool interactive = false)
		{
			return ReadManyBytes(EmptyToken.Value, buffer, interactive);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Task<int> ReadManyBytesAsync(CancellationToken token, Memory<byte> buffer, bool interactive = false)
		{
			return ReadManyBytes(token, buffer, interactive);
		}

		private static NotImplementedException NotImplemented(string feature)
		{
			return new NotImplementedException("Feature '" + feature + "' is not implemented");
		}

		private static InvalidDataException InvalidHeaderChecksum()
		{
			return new InvalidDataException("Invalid LZ4 frame header checksum");
		}

		private static InvalidDataException MagicNumberExpected()
		{
			return new InvalidDataException("LZ4 frame magic number expected");
		}

		private static InvalidDataException UnknownFrameVersion(int version)
		{
			return new InvalidDataException($"LZ4 frame version {version} is not supported");
		}

		private static InvalidDataException InvalidChecksum(string type)
		{
			return new InvalidDataException("Invalid " + type + " checksum");
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!disposing)
			{
				return;
			}
			try
			{
				CloseFrame();
			}
			finally
			{
				_stash.Dispose();
				ReleaseResources();
			}
		}

		protected virtual void ReleaseResources()
		{
		}

		protected virtual Task ReleaseResourcesAsync()
		{
			return Task.CompletedTask;
		}

		public void Dispose()
		{
			Dispose(disposing: true);
		}

		private int ReadMeta(EmptyToken _, int length, bool optional = false)
		{
			byte[] data = _stash.Data;
			int head = _stash.Head;
			return _reader.TryReadBlock(ref _stream, data, head, length, optional);
		}

		private async Task<int> ReadMeta(CancellationToken token, int length, bool optional = false)
		{
			byte[] data = _stash.Data;
			int head = _stash.Head;
			int result;
			(_stream, result) = (ReadResult<TStreamState>)(ref await _reader.TryReadBlockAsync(_stream, data, head, length, optional, token).Weave());
			return result;
		}

		private void ReadData(EmptyToken _, int length)
		{
			_reader.TryReadBlock(ref _stream, _buffer, 0, length, optional: false);
		}

		private async Task ReadData(CancellationToken token, int length)
		{
			_stream = (await _reader.TryReadBlockAsync(_stream, _buffer, 0, length, optional: false, token).Weave()).Stream;
		}
	}
	public class ByteSpanLZ4FrameReader : LZ4FrameReader<ByteSpanAdapter, int>
	{
		public ByteSpanLZ4FrameReader(UnsafeByteSpan span, Func<ILZ4Descriptor, ILZ4Decoder> decoderFactory)
			: base(new ByteSpanAdapter(span), 0, decoderFactory)
		{
		}
	}
	public class ByteMemoryLZ4FrameReader : LZ4FrameReader<ByteMemoryReadAdapter, int>
	{
		public ByteMemoryLZ4FrameReader(ReadOnlyMemory<byte> memory, Func<ILZ4Descriptor, ILZ4Decoder> decoderFactory)
			: base(new ByteMemoryReadAdapter(memory), 0, decoderFactory)
		{
		}
	}
	public class ByteSequenceLZ4FrameReader : LZ4FrameReader<ByteSequenceAdapter, ReadOnlySequence<byte>>
	{
		public ByteSequenceLZ4FrameReader(ReadOnlySequence<byte> sequence, Func<ILZ4Descriptor, ILZ4Decoder> decoderFactory)
			: base(default(ByteSequenceAdapter), sequence, decoderFactory)
		{
		}//IL_000a: Unknown result type (might be due to invalid IL or missing references)

	}
	public class StreamLZ4FrameReader : LZ4FrameReader<StreamAdapter, EmptyState>
	{
		private readonly Stream _stream;

		private readonly bool _leaveOpen;

		public StreamLZ4FrameReader(Stream stream, bool leaveOpen, Func<ILZ4Descriptor, ILZ4Decoder> decoderFactory)
			: base(new StreamAdapter(stream), default(EmptyState), decoderFactory)
		{
			_stream = stream;
			_leaveOpen = leaveOpen;
		}

		protected override void Dispose(bool disposing)
		{
			CloseFrame();
			if (disposing && !_leaveOpen)
			{
				_stream.Dispose();
			}
			base.Dispose(disposing);
		}
	}
	public class PipeLZ4FrameReader : LZ4FrameReader<PipeReaderAdapter, EmptyState>
	{
		private readonly PipeReader _pipe;

		private readonly bool _leaveOpen;

		public PipeLZ4FrameReader(PipeReader pipe, bool leaveOpen, Func<ILZ4Descriptor, ILZ4Decoder> decoderFactory)
			: base(new PipeReaderAdapter(pipe), default(EmptyState), decoderFactory)
		{
			_pipe = pipe;
			_leaveOpen = leaveOpen;
		}

		protected override void ReleaseResources()
		{
			if (!_leaveOpen)
			{
				_pipe.Complete((Exception)null);
			}
			base.ReleaseResources();
		}

		protected override async Task ReleaseResourcesAsync()
		{
			if (!_leaveOpen)
			{
				await _pipe.CompleteAsync((Exception)null).Weave();
			}
			await base.ReleaseResourcesAsync().Weave();
		}
	}
	public class LZ4FrameReaderAsStream : LZ4StreamEssentials<ILZ4FrameReader>
	{
		private readonly bool _interactive;

		public override bool CanRead => true;

		public override long Length => base.InnerResource.GetFrameLength() ?? (-1);

		public override long Position => base.InnerResource.GetBytesRead();

		public LZ4FrameReaderAsStream(ILZ4FrameReader reader, bool doNotDispose = false, bool interactive = false)
			: base(reader, doNotDispose)
		{
			_interactive = interactive;
		}

		public override int ReadByte()
		{
			return base.InnerResource.ReadOneByte();
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			return base.InnerResource.ReadManyBytes(buffer.AsSpan(offset, count), _interactive);
		}

		public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken token)
		{
			return base.InnerResource.ReadManyBytesAsync(token, buffer.AsMemory(offset, count), _interactive);
		}
	}
	public class LZ4FrameWriter<TStreamWriter, TStreamState> : ILZ4FrameWriter, IDisposable where TStreamWriter : IStreamWriter<TStreamState>
	{
		private readonly TStreamWriter _writer;

		private TStreamState _stream;

		private Stash _stash = new Stash();

		private readonly Func<ILZ4Descriptor, ILZ4Encoder> _encoderFactory;

		private ILZ4Descriptor? _descriptor;

		private ILZ4Encoder? _encoder;

		private byte[]? _buffer;

		private long _bytesWritten;

		private State _contentChecksum;

		protected TStreamState StreamState => _stream;

		private async Task WriteBlock(CancellationToken token, BlockInfo block)
		{
			if (block.Ready)
			{
				_stash.Poke4(BlockLengthCode(in block));
				await FlushMeta(token).Weave();
				await WriteData(token, block).Weave();
				_stash.TryPoke4(BlockChecksum(block));
				await FlushMeta(token, eof: true).Weave();
			}
		}

		private Task WriteOneByte(CancellationToken token, byte value)
		{
			return WriteManyBytes(token, OneByteBuffer(in token, value));
		}

		private async Task WriteManyBytes(CancellationToken token, ReadOnlyMemory<byte> buffer)
		{
			if (TryStashFrame())
			{
				await FlushMeta(token).Weave();
			}
			if (_descriptor.ContentChecksum)
			{
				UpdateContentChecksum(buffer.ToSpan());
			}
			int offset = 0;
			int count = buffer.Length;
			while (count > 0)
			{
				BlockInfo block = TopupAndEncode(buffer.ToSpan(), ref offset, ref count);
				if (block.Ready)
				{
					await WriteBlock(token, block).Weave();
				}
			}
		}

		private async Task<bool> OpenFrame(CancellationToken token)
		{
			if (!TryStashFrame())
			{
				return false;
			}
			await FlushMeta(token).Weave();
			return true;
		}

		private async Task CloseFrame(CancellationToken token)
		{
			if (_encoder == null)
			{
				return;
			}
			try
			{
				await WriteFrameTail(token).Weave();
				if (_buffer != null)
				{
					ReleaseBuffer(_buffer);
				}
				((IDisposable)_encoder).Dispose();
			}
			finally
			{
				_encoder = null;
				_descriptor = null;
				_buffer = null;
			}
		}

		private async Task WriteFrameTail(CancellationToken token)
		{
			BlockInfo block = FlushAndEncode();
			if (block.Ready)
			{
				await WriteBlock(token, block).Weave();
			}
			_stash.Poke4(0u);
			_stash.TryPoke4(ContentChecksum());
			await FlushMeta(token, eof: true).Weave();
		}

		private void WriteBlock(EmptyToken token, BlockInfo block)
		{
			if (block.Ready)
			{
				_stash.Poke4(BlockLengthCode(in block));
				FlushMeta(token);
				WriteData(token, block);
				_stash.TryPoke4(BlockChecksum(block));
				FlushMeta(token, eof: true);
			}
		}

		private void WriteOneByte(EmptyToken token, byte value)
		{
			WriteManyBytes(token, OneByteBuffer(in token, value));
		}

		private void WriteManyBytes(EmptyToken token, ReadOnlySpan<byte> buffer)
		{
			if (TryStashFrame())
			{
				FlushMeta(token);
			}
			if (_descriptor.ContentChecksum)
			{
				UpdateContentChecksum(buffer.ToSpan());
			}
			int offset = 0;
			int count = buffer.Length;
			while (count > 0)
			{
				BlockInfo block = TopupAndEncode(buffer.ToSpan(), ref offset, ref count);
				if (block.Ready)
				{
					WriteBlock(token, block);
				}
			}
		}

		private bool OpenFrame(EmptyToken token)
		{
			if (!TryStashFrame())
			{
				return false;
			}
			FlushMeta(token);
			return true;
		}

		private void CloseFrame(EmptyToken token)
		{
			if (_encoder == null)
			{
				return;
			}
			try
			{
				WriteFrameTail(token);
				if (_buffer != null)
				{
					ReleaseBuffer(_buffer);
				}
				((IDisposable)_encoder).Dispose();
			}
			finally
			{
				_encoder = null;
				_descriptor = null;
				_buffer = null;
			}
		}

		private void WriteFrameTail(EmptyToken token)
		{
			BlockInfo block = FlushAndEncode();
			if (block.Ready)
			{
				WriteBlock(token, block);
			}
			_stash.Poke4(0u);
			_stash.TryPoke4(ContentChecksum());
			FlushMeta(token, eof: true);
		}

		public LZ4FrameWriter(TStreamWriter writer, TStreamState stream, Func<ILZ4Descriptor, ILZ4Encoder> encoderFactory, ILZ4Descriptor descriptor)
		{
			_writer = writer;
			_stream = stream;
			_descriptor = descriptor;
			_encoderFactory = encoderFactory;
			_bytesWritten = 0L;
		}

		private bool TryStashFrame()
		{
			if (_encoder != null)
			{
				return false;
			}
			_stash.Poke4(407708164u);
			int head = _stash.Head;
			bool chaining = _descriptor.Chaining;
			bool blockChecksum = _descriptor.BlockChecksum;
			bool contentChecksum = _descriptor.ContentChecksum;
			bool hasValue = _descriptor.ContentLength.HasValue;
			bool hasValue2 = _descriptor.Dictionary.HasValue;
			int num = 0x40 | (((!chaining) ? 1 : 0) << 5) | ((blockChecksum ? 1 : 0) << 4) | ((hasValue ? 1 : 0) << 3) | ((contentChecksum ? 1 : 0) << 2) | (hasValue2 ? 1 : 0);
			int blockSize = _descriptor.BlockSize;
			int num2 = MaxBlockSizeCode(blockSize) << 4;
			_stash.Poke2((ushort)(((uint)num & 0xFFu) | (uint)((num2 & 0xFF) << 8)));
			if (hasValue)
			{
				throw NotImplemented("ContentSize feature is not implemented");
			}
			if (hasValue2)
			{
				throw NotImplemented("Predefined dictionaries feature is not implemented");
			}
			if (contentChecksum)
			{
				InitializeContentChecksum();
			}
			byte value = (byte)(_stash.Digest(head) >> 8);
			_stash.Poke1(value);
			_encoder = CreateEncoder();
			_buffer = AllocateBuffer(LZ4Codec.MaximumOutputSize(blockSize));
			return true;
		}

		protected virtual byte[] AllocateBuffer(int size)
		{
			return BufferPool.Alloc(size, false);
		}

		protected virtual void ReleaseBuffer(byte[] buffer)
		{
			BufferPool.Free(buffer);
		}

		private ILZ4Encoder CreateEncoder()
		{
			ILZ4Encoder obj = _encoderFactory(_descriptor);
			if (obj.BlockSize > _descriptor.BlockSize)
			{
				throw InvalidValue("BlockSize is greater than declared");
			}
			return obj;
		}

		private BlockInfo TopupAndEncode(ReadOnlySpan<byte> buffer, ref int offset, ref int count)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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)
			int num = default(int);
			int length = default(int);
			EncoderAction action = LZ4EncoderExtensions.TopupAndEncode(_encoder, buffer.Slice(offset, count), _buffer.AsSpan(), false, true, ref num, ref length);
			_bytesWritten += num;
			offset += num;
			count -= num;
			return new BlockInfo(_buffer, action, length);
		}

		private BlockInfo FlushAndEncode()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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)
			int length = default(int);
			EncoderAction action = LZ4EncoderExtensions.FlushAndEncode(_encoder, _buffer.AsSpan(), true, ref length);
			return new BlockInfo(_buffer, action, length);
		}

		private static uint BlockLengthCode(in BlockInfo block)
		{
			return (uint)block.Length | ((!block.Compressed) ? 2147483648u : 0u);
		}

		private void InitializeContentChecksum()
		{
			XXH32.Reset(ref _contentChecksum, 0u);
		}

		private void UpdateContentChecksum(ReadOnlySpan<byte> buffer)
		{
			XXH32.Update(ref _contentChecksum, buffer);
		}

		private uint? BlockChecksum(BlockInfo block)
		{
			if (!_descriptor.BlockChecksum)
			{
				return null;
			}
			return XXH32.DigestOf(block.Buffer, block.Offset, block.Length);
		}

		private uint? ContentChecksum()
		{
			if (!_descriptor.ContentChecksum)
			{
				return null;
			}
			return XXH32.Digest(ref _contentChecksum);
		}

		private int MaxBlockSizeCode(int blockSize)
		{
			if (blockSize > 65536)
			{
				if (blockSize > 262144)
				{
					if (blockSize > 1048576)
					{
						if (blockSize > 4194304)
						{
							throw InvalidBlockSize(blockSize);
						}
						return 7;
					}
					return 6;
				}
				return 5;
			}
			return 4;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public long GetBytesWritten()
		{
			return _bytesWritten;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteOneByte(byte value)
		{
			WriteOneByte(EmptyToken.Value, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Task WriteOneByteAsync(CancellationToken token, byte value)
		{
			return WriteOneByte(token, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteManyBytes(ReadOnlySpan<byte> buffer)
		{
			WriteManyBytes(EmptyToken.Value, buffer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Task WriteManyBytesAsync(CancellationToken token, ReadOnlyMemory<byte> buffer)
		{
			return WriteManyBytes(token, buffer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool OpenFrame()
		{
			return OpenFrame(EmptyToken.Value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Task<bool> OpenFrameAsync(CancellationToken token = default(CancellationToken))
		{
			return OpenFrame(token);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void CloseFrame()
		{
			CloseFrame(EmptyToken.Value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Task CloseFrameAsync(CancellationToken token = default(CancellationToken))
		{
			return CloseFrame(token);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!disposing)
			{
				return;
			}
			try
			{
				CloseFrame();
			}
			finally
			{
				_stash.Dispose();
				ReleaseResources();
			}
		}

		public void Dispose()
		{
			Dispose(disposing: true);
		}

		protected virtual void ReleaseResources()
		{
		}

		protected virtual Task ReleaseResourcesAsync()
		{
			return Task.CompletedTask;
		}

		private void FlushMeta(EmptyToken _, bool eof = false)
		{
			int num = _stash.Flush();
			if (num > 0)
			{
				_writer.Write(ref _stream, _stash.Data, 0, num);
			}
			if (eof && _writer.CanFlush)
			{
				_writer.Flush(ref _stream);
			}
		}

		private async Task FlushMeta(CancellationToken token, bool eof = false)
		{
			int num = _stash.Flush();
			if (num > 0)
			{
				_stream = await _writer.WriteAsync(_stream, _stash.Data, 0, num, token).Weave();
			}
			if (eof && _writer.CanFlush)
			{
				_stream = await _writer.FlushAsync(_stream, token).Weave();
			}
		}

		private void WriteData(EmptyToken _, BlockInfo block)
		{
			_writer.Write(ref _stream, block.Buffer, block.Offset, block.Length);
		}

		private async Task WriteData(CancellationToken token, BlockInfo block)
		{
			_stream = await _writer.WriteAsync(_stream, block.Buffer, block.Offset, block.Length, token).Weave();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private Span<byte> OneByteBuffer(in EmptyToken _, byte value)
		{
			return _stash.OneByteSpan(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private Memory<byte> OneByteBuffer(in CancellationToken _, byte value)
		{
			return _stash.OneByteMemory(value);
		}

		private NotImplementedException NotImplemented(string operation)
		{
			return new NotImplementedException("Feature " + operation + " has not been implemented in " + GetType().Name);
		}

		private static ArgumentException InvalidValue(string description)
		{
			return new ArgumentException(description);
		}

		private protected ArgumentException InvalidBlockSize(int blockSize)
		{
			return InvalidValue($"Invalid block size ${blockSize} for {GetType().Name}");
		}
	}
	public class ByteBufferLZ4FrameWriter<TBufferWriter> : LZ4FrameWriter<ByteBufferAdapter<TBufferWriter>, TBufferWriter> where TBufferWriter : IBufferWriter<byte>
	{
		public TBufferWriter BufferWriter => base.StreamState;

		public ByteBufferLZ4FrameWriter(TBufferWriter stream, Func<ILZ4Descriptor, ILZ4Encoder> encoderFactory, ILZ4Descriptor descriptor)
			: base(default(ByteBufferAdapter<TBufferWriter>), stream, encoderFactory, descriptor)
		{
		}
	}
	public class ByteBufferLZ4FrameWriter : ByteBufferLZ4FrameWriter<IBufferWriter<byte>>
	{
		public ByteBufferLZ4FrameWriter(IBufferWriter<byte> stream, Func<ILZ4Descriptor, ILZ4Encoder> encoderFactory, ILZ4Descriptor descriptor)
			: base(stream, encoderFactory, descriptor)
		{
		}
	}
	public class ByteMemoryLZ4FrameWriter : LZ4FrameWriter<ByteMemoryWriteAdapter, int>
	{
		public int CompressedLength => base.StreamState;

		public ByteMemoryLZ4FrameWriter(Memory<byte> memory, Func<ILZ4Descriptor, ILZ4Encoder> encoderFactory, ILZ4Descriptor descriptor)
			: base(new ByteMemoryWriteAdapter(memory), 0, encoderFactory, descriptor)
		{
		}
	}
	public class ByteSpanLZ4FrameWriter : LZ4FrameWriter<ByteSpanAdapter, int>
	{
		public int CompressedLength => base.StreamState;

		public ByteSpanLZ4FrameWriter(UnsafeByteSpan span, Func<ILZ4Descriptor, ILZ4Encoder> encoderFactory, ILZ4Descriptor descriptor)
			: base(new ByteSpanAdapter(span), 0, encoderFactory, descriptor)
		{
		}
	}
	public class StreamLZ4FrameWriter : LZ4FrameWriter<StreamAdapter, EmptyState>
	{
		private readonly Stream _stream;

		private readonly bool _leaveOpen;

		public StreamLZ4FrameWriter(Stream stream, bool leaveOpen, Func<ILZ4Descriptor, ILZ4Encoder> encoderFactory, ILZ4Descriptor descriptor)
			: base(new StreamAdapter(stream), default(EmptyState), encoderFactory, descriptor)
		{
			_stream = stream;
			_leaveOpen = leaveOpen;
		}

		protected override void ReleaseResources()
		{
			if (!_leaveOpen)
			{
				_stream.Dispose();
			}
			base.ReleaseResources();
		}

		protected override async Task ReleaseResourcesAsync()
		{
			if (!_leaveOpen)
			{
				_stream.Dispose();
			}
			await base.ReleaseResourcesAsync().Weave();
		}
	}
	public class PipeLZ4FrameWriter : LZ4FrameWriter<PipeWriterAdapter, EmptyState>
	{
		private readonly PipeWriter _pipe;

		private readonly bool _leaveOpen;

		public PipeLZ4FrameWriter(PipeWriter pipe, bool leaveOpen, Func<ILZ4Descriptor, ILZ4Encoder> encoderFactory, ILZ4Descriptor descriptor)
			: base(new PipeWriterAdapter(pipe), default(EmptyState), encoderFactory, descriptor)
		{
			_pipe = pipe;
			_leaveOpen = leaveOpen;
		}

		protected override void ReleaseResources()
		{
			if (!_leaveOpen)
			{
				_pipe.Complete((Exception)null);
			}
			base.ReleaseResources();
		}

		protected override async Task ReleaseResourcesAsync()
		{
			if (!_leaveOpen)
			{
				await _pipe.CompleteAsync((Exception)null).Weave();
			}
			await base.ReleaseResourcesAsync().Weave();
		}
	}
	public class LZ4FrameWriterAsStream : LZ4StreamEssentials<ILZ4FrameWriter>
	{
		public override bool CanWrite => true;

		public override long Length => base.InnerResource.GetBytesWritten();

		public override long Position => base.InnerResource.GetBytesWritten();

		public LZ4FrameWriterAsStream(ILZ4FrameWriter writer, bool doNotDispose = false)
			: base(writer, doNotDispose)
		{
		}

		public override void WriteByte(byte value)
		{
			base.InnerResource.WriteOneByte(value);
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			base.InnerResource.WriteManyBytes(buffer.AsSpan(offset, count));
		}

		public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken token)
		{
			return base.InnerResource.WriteManyBytesAsync(token, buffer.AsMemory(offset, count));
		}
	}
}
namespace K4os.Compression.LZ4.Streams.Adapters
{
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public readonly struct ByteBufferAdapter<TBufferWriter> : IStreamWriter<TBufferWriter> where TBufferWriter : IBufferWriter<byte>
	{
		public bool CanFlush
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return false;
			}
		}

		public void Write(ref TBufferWriter state, byte[] buffer, int offset, int length)
		{
			if (length > 0)
			{
				Span<byte> span = buffer.AsSpan(offset, length);
				Span<byte> span2 = ((IBufferWriter<byte>)state).GetSpan(length);
				span.CopyTo(span2);
				((IBufferWriter<byte>)state).Advance(length);
			}
		}

		public Task<TBufferWriter> WriteAsync(TBufferWriter state, byte[] buffer, int offset, int length, CancellationToken token)
		{
			Write(ref state, buffer, offset, length);
			return Task.FromResult(state);
		}

		public void Flush(ref TBufferWriter state)
		{
		}

		public Task<TBufferWriter> FlushAsync(TBufferWriter state, CancellationToken token)
		{
			return Task.FromResult(state);
		}
	}
	public readonly struct ByteMemoryReadAdapter : IStreamReader<int>
	{
		private readonly ReadOnlyMemory<byte> _memory;

		public ByteMemoryReadAdapter(ReadOnlyMemory<byte> memory)
		{
			_memory = memory;
		}

		internal int CopyToBuffer(int head, byte[] buffer, int offset, int length)
		{
			length = Math.Min(_memory.Length - head, length);
			if (length <= 0)
			{
				return 0;
			}
			ReadOnlySpan<byte> readOnlySpan = _memory.Span.Slice(head, length);
			Span<byte> destination = buffer.AsSpan(offset, length);
			readOnlySpan.CopyTo(destination);
			return length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static int Advance(ref int state, int length)
		{
			if (length > 0)
			{
				state += length;
			}
			return length;
		}

		public int Read(ref int state, byte[] buffer, int offset, int length)
		{
			return Advance(ref state, CopyToBuffer(state, buffer, offset, length));
		}

		public Task<ReadResult<int>> ReadAsync(int state, byte[] buffer, int offset, int length, CancellationToken token)
		{
			token.ThrowIfCancellationRequested();
			int bytes = Read(ref state, buffer, offset, length);
			return Task.FromResult(ReadResult.Create(state, bytes));
		}
	}
	public readonly struct ByteMemoryWriteAdapter : IStreamWriter<int>
	{
		private readonly Memory<byte> _memory;

		public bool CanFlush
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return false;
			}
		}

		public ByteMemoryWriteAdapter(Memory<byte> memory)
		{
			_memory = memory;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static void Advance(ref int memory, int length)
		{
			if (length > 0)
			{
				memory += length;
			}
		}

		public void Write(ref int state, byte[] buffer, int offset, int length)
		{
			if (length > 0)
			{
				if (length > _memory.Length - state)
				{
					throw new ArgumentOutOfRangeException("length");
				}
				Span<byte> span = buffer.AsSpan(offset, length);
				Span<byte> destination = _memory.Span.Slice(state, length);
				span.CopyTo(destination);
				Advance(ref state, length);
			}
		}

		public Task<int> WriteAsync(int state, byte[] buffer, int offset, int length, CancellationToken token)
		{
			token.ThrowIfCancellationRequested();
			Write(ref state, buffer, offset, length);
			return Task.FromResult(state);
		}

		public void Flush(ref int state)
		{
		}

		public Task<int> FlushAsync(int state, CancellationToken token)
		{
			return Task.FromResult(state);
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public struct ByteSequenceAdapter : IStreamReader<ReadOnlySequence<byte>>
	{
		public int Read(ref ReadOnlySequence<byte> state, byte[] buffer, int offset, int length)
		{
			//IL_0041: 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)
			if (length <= 0)
			{
				return 0;
			}
			ReadOnlySpan<byte> span = state.First.Span;
			int num = Math.Min(span.Length, length);
			span.Slice(0, num).CopyTo(buffer.AsSpan(offset));
			state = state.Slice((long)num);
			return num;
		}

		public Task<ReadResult<ReadOnlySequence<byte>>> ReadAsync(ReadOnlySequence<byte> state, byte[] buffer, int offset, int length, CancellationToken token)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			token.ThrowIfCancellationRequested();
			int bytes = Read(ref state, buffer, offset, length);
			return Task.FromResult(ReadResult.Create<ReadOnlySequence<byte>>(state, bytes));
		}
	}
	public class ByteSpanAdapter : IStreamReader<int>, IStreamWriter<int>
	{
		private readonly UnsafeByteSpan _span;

		public bool CanFlush
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return false;
			}
		}

		public ByteSpanAdapter(UnsafeByteSpan span)
		{
			_span = span;
		}

		public int Read(ref int state, byte[] buffer, int offset, int length)
		{
			length = Math.Min(_span.Length - state, length);
			if (length <= 0)
			{
				return 0;
			}
			Span<byte> span = _span.Span;
			span = span.Slice(state, length);
			span.CopyTo(buffer.AsSpan(offset, length));
			state += length;
			return length;
		}

		public Task<ReadResult<int>> ReadAsync(int state, byte[] buffer, int offset, int length, CancellationToken token)
		{
			token.ThrowIfCancellationRequested();
			int bytes = Read(ref state, buffer, offset, length);
			return Task.FromResult(ReadResult.Create(state, bytes));
		}

		public void Write(ref int state, byte[] buffer, int offset, int length)
		{
			if (length > 0)
			{
				int num = _span.Length - state;
				if (length > num)
				{
					throw new ArgumentOutOfRangeException("length");
				}
				buffer.AsSpan(offset, length).CopyTo(_span.Span.Slice(state, length));
				state += length;
			}
		}

		public Task<int> WriteAsync(int state, byte[] buffer, int offset, int length, CancellationToken token)
		{
			token.ThrowIfCancellationRequested();
			Write(ref state, buffer, offset, length);
			return Task.FromResult(state);
		}

		public void Flush(ref int state)
		{
		}

		public Task<int> FlushAsync(int state, CancellationToken token)
		{
			return Task.FromResult(state);
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public readonly struct EmptyState
	{
	}
	public readonly struct PipeReaderAdapter : IStreamReader<EmptyState>
	{
		private readonly PipeReader _reader;

		public PipeReaderAdapter(PipeReader reader)
		{
			_reader = reader;
		}

		private static void CheckSyncOverAsync()
		{
			if (SynchronizationContext.Current != null)
			{
				throw new InvalidOperationException("Asynchronous methods cannot be called synchronously when executed in SynchronizationContext.");
			}
		}

		public int Read(ref EmptyState state, byte[] buffer, int offset, int length)
		{
			CheckSyncOverAsync();
			int result;
			(state, result) = (ReadResult<EmptyState>)(ref ReadAsync(state, buffer, offset, length, CancellationToken.None).GetAwaiter().GetResult());
			return result;
		}

		public async Task<ReadResult<EmptyState>> ReadAsync(EmptyState state, byte[] buffer, int offset, int length, CancellationToken token)
		{
			if (length <= 0)
			{
				return ReadResult.Create(state);
			}
			ReadOnlySequence<byte> sequence = await ReadFromPipe(_reader, length, token).Weave();
			return ReadFromSequence(_reader, sequence, buffer.AsSpan(offset, length));
		}

		private static async Task<ReadOnlySequence<byte>> ReadFromPipe(PipeReader reader, int length, CancellationToken token)
		{
			ReadResult val = await reader.ReadAsync(token).Weave();
			if (((ReadResult)(ref val)).IsCanceled)
			{
				ThrowPendingReadsCancelled();
			}
			return ((ReadResult)(ref val)).Buffer;
		}

		private static ReadResult<EmptyState> ReadFromSequence(PipeReader reader, ReadOnlySequence<byte> sequence, Span<byte> buffer)
		{
			//IL_0068: 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)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			int num2 = buffer.Length;
			while (!sequence.IsEmpty && num2 > 0)
			{
				ReadOnlySpan<byte> span = sequence.First.Span;
				int num3 = Math.Min(span.Length, num2);
				span.Slice(0, num3).CopyTo(buffer.Slice(num));
				sequence = sequence.Slice((long)num3);
				num += num3;
				num2 -= num3;
			}
			reader.AdvanceTo(sequence.Start);
			return ReadResult.Create(default(EmptyState), num);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		[DoesNotReturn]
		private static void ThrowPendingReadsCancelled()
		{
			throw new OperationCanceledException("Pending PipeReader operations has been cancelled");
		}
	}
	public readonly struct PipeWriterAdapter : IStreamWriter<EmptyState>
	{
		private readonly PipeWriter _writer;

		public bool CanFlush => true;

		public PipeWriterAdapter(PipeWriter writer)
		{
			_writer = writer;
		}

		public void Write(ref EmptyState state, byte[] buffer, int offset, int length)
		{
			CheckSyncOverAsync();
			state = WriteAsync(state, buffer, offset, length, CancellationToken.None).GetAwaiter().GetResult();
		}

		public async Task<EmptyState> WriteAsync(EmptyState state, byte[] buffer, int offset, int length, CancellationToken token)
		{
			await _writer.WriteAsync((ReadOnlyMemory<byte>)buffer.AsMemory(offset, length), token).Weave();
			return state;
		}

		public void Flush(ref EmptyState state)
		{
			CheckSyncOverAsync();
			state = FlushAsync(state, CancellationToken.None).GetAwaiter().GetResult();
		}

		public async Task<EmptyState> FlushAsync(EmptyState state, CancellationToken token)
		{
			await _writer.FlushAsync(token).Weave();
			return state;
		}

		private static void CheckSyncOverAsync()
		{
			if (SynchronizationContext.Current != null)
			{
				throw new InvalidOperationException("Asynchronous methods cannot be called synchronously when executed in SynchronizationContext.");
			}
		}
	}
	public readonly struct StreamAdapter : IStreamReader<EmptyState>, IStreamWriter<EmptyState>
	{
		private readonly Stream _stream;

		public bool CanFlush
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return false;
			}
		}

		public StreamAdapter(Stream stream)
		{
			_stream = stream;
		}

		public int Read(ref EmptyState state, byte[] buffer, int offset, int length)
		{
			return _stream.Read(buffer, offset, length);
		}

		public async Task<ReadResult<EmptyState>> ReadAsync(EmptyState state, byte[] buffer, int offset, int length, CancellationToken token)
		{
			return ReadResult.Create(state, await _stream.ReadAsync(buffer, offset, length, token).Weave());
		}

		public void Write(ref EmptyState state, byte[] buffer, int offset, int length)
		{
			_stream.Write(buffer, offset, length);
		}

		public async Task<EmptyState> WriteAsync(EmptyState state, byte[] buffer, int offset, int length, CancellationToken token)
		{
			await _stream.WriteAsync(buffer, offset, length, token).Weave();
			return state;
		}

		public void Flush(ref EmptyState state)
		{
		}

		public Task<EmptyState> FlushAsync(EmptyState state, CancellationToken token)
		{
			return Task.FromResult(state);
		}
	}
	public readonly struct UnsafeByteSpan
	{
		public unsafe byte* Bytes { get; }

		public int Length { get; }

		public unsafe Span<byte> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return new Span<byte>(Bytes, Length);
			}
		}

		public unsafe UnsafeByteSpan(void* bytes, int length)
		{
			Bytes = (byte*)bytes;
			Length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static UnsafeByteSpan Create(void* bytes, int length)
		{
			return new UnsafeByteSpan(bytes, length);
		}
	}
}
namespace K4os.Compression.LZ4.Streams.Abstractions
{
	public interface ILZ4FrameReader : IDisposable
	{
		bool OpenFrame();

		Task<bool> OpenFrameAsync(CancellationToken token);

		long? GetFrameLength();

		Task<long?> GetFrameLengthAsync(CancellationToken token);

		int ReadOneByte();

		Task<int> ReadOneByteAsync(CancellationToken token);

		int ReadManyBytes(Span<byte> buffer, bool interactive = false);

		Task<int> ReadManyBytesAsync(CancellationToken token, Memory<byte> buffer, bool interactive = false);

		long GetBytesRead();

		void CloseFrame();
	}
	public interface ILZ4FrameWriter : IDisposable
	{
		bool OpenFrame();

		Task<bool> OpenFrameAsync(CancellationToken token);

		void WriteOneByte(byte value);

		Task WriteOneByteAsync(CancellationToken token, byte value);

		void WriteManyBytes(ReadOnlySpan<byte> buffer);

		Task WriteManyBytesAsync(CancellationToken token, ReadOnlyMemory<byte> buffer);

		long GetBytesWritten();

		void CloseFrame();

		Task CloseFrameAsync(CancellationToken token);
	}
	public interface IStreamReader<TStreamState>
	{
		int Read(ref TStreamState state, byte[] buffer, int offset, int length);

		Task<ReadResult<TStreamState>> ReadAsync(TStreamState state, byte[] buffer, int offset, int length, CancellationToken token);
	}
	public interface IStreamWriter<TStreamState>
	{
		bool CanFlush { get; }

		void Write(ref TStreamState state, byte[] buffer, int offset, int length);

		Task<TStreamState> WriteAsync(TStreamState state, byte[] buffer, int offset, int length, CancellationToken token);

		void Flush(ref TStreamState state);

		Task<TStreamState> FlushAsync(TStreamState state, CancellationToken token);
	}
	public record struct ReadResult<TStreamState>(TStreamState Stream, int Bytes);
	public static class ReadResult
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadResult<TStreamState> Create<TStreamState>(TStreamState stream, int bytes = 0)
		{
			return new ReadResult<TStreamState>(stream, bytes);
		}
	}
}

K4os.Hash.xxHash.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("Milosz Krajewski")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Milosz Krajewski")]
[assembly: AssemblyDescription("xxHash hash implementation for .NET")]
[assembly: AssemblyFileVersion("1.0.8")]
[assembly: AssemblyInformationalVersion("1.0.8")]
[assembly: AssemblyProduct("K4os.Hash.xxHash")]
[assembly: AssemblyTitle("K4os.Hash.xxHash")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MiloszKrajewski/K4os.Hash.xxHash")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.8.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}
namespace K4os.Hash.xxHash
{
	public class HashAlgorithmAdapter : HashAlgorithm
	{
		private readonly Action _reset;

		private readonly Action<byte[], int, int> _update;

		private readonly Func<byte[]> _digest;

		public override int HashSize { get; }

		public override byte[] Hash => _digest();

		public HashAlgorithmAdapter(int hashSize, Action reset, Action<byte[], int, int> update, Func<byte[]> digest)
		{
			_reset = reset;
			_update = update;
			_digest = digest;
			HashSize = hashSize;
		}

		protected override void HashCore(byte[] array, int ibStart, int cbSize)
		{
			_update(array, ibStart, cbSize);
		}

		protected override byte[] HashFinal()
		{
			return _digest();
		}

		public override void Initialize()
		{
			_reset();
		}
	}
	public class XXH
	{
		protected XXH()
		{
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal unsafe static uint XXH_read32(void* p)
		{
			return *(uint*)p;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal unsafe static ulong XXH_read64(void* p)
		{
			return *(ulong*)p;
		}

		internal unsafe static void XXH_zero(void* target, int length)
		{
			System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(target, (byte)0, (uint)length);
		}

		internal unsafe static void XXH_copy(void* target, void* source, int length)
		{
			System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(target, source, (uint)length);
		}

		internal static void Validate(byte[] bytes, int offset, int length)
		{
			if (bytes == null || offset < 0 || length < 0 || offset + length > bytes.Length)
			{
				throw new ArgumentException("Invalid buffer boundaries");
			}
		}
	}
	public class XXH32 : XXH
	{
		public struct State
		{
			public uint total_len_32;

			public bool large_len;

			public uint v1;

			public uint v2;

			public uint v3;

			public uint v4;

			public unsafe fixed uint mem32[4];

			public uint memsize;
		}

		private const uint PRIME32_1 = 2654435761u;

		private const uint PRIME32_2 = 2246822519u;

		private const uint PRIME32_3 = 3266489917u;

		private const uint PRIME32_4 = 668265263u;

		private const uint PRIME32_5 = 374761393u;

		public const uint EmptyHash = 46947589u;

		private State _state;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static uint XXH32_rotl(uint x, int r)
		{
			return (x << r) | (x >> 32 - r);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static uint XXH32_round(uint seed, uint input)
		{
			return XXH32_rotl(seed + (uint)((int)input * -2048144777), 13) * 2654435761u;
		}

		private unsafe static uint XXH32_hash(void* input, int len, uint seed)
		{
			byte* ptr = (byte*)input;
			byte* ptr2 = ptr + len;
			uint num5;
			if (len >= 16)
			{
				byte* ptr3 = ptr2 - 16;
				uint num = (uint)((int)seed + -1640531535 + -2048144777);
				uint num2 = seed + 2246822519u;
				uint num3 = seed;
				uint num4 = seed - 2654435761u;
				do
				{
					num = XXH32_round(num, XXH.XXH_read32(ptr));
					num2 = XXH32_round(num2, XXH.XXH_read32(ptr + 4));
					num3 = XXH32_round(num3, XXH.XXH_read32(ptr + 8));
					num4 = XXH32_round(num4, XXH.XXH_read32(ptr + 12));
					ptr += 16;
				}
				while (ptr <= ptr3);
				num5 = XXH32_rotl(num, 1) + XXH32_rotl(num2, 7) + XXH32_rotl(num3, 12) + XXH32_rotl(num4, 18);
			}
			else
			{
				num5 = seed + 374761393;
			}
			num5 += (uint)len;
			for (; ptr + 4 <= ptr2; ptr += 4)
			{
				num5 = XXH32_rotl(num5 + (uint)((int)XXH.XXH_read32(ptr) * -1028477379), 17) * 668265263;
			}
			for (; ptr < ptr2; ptr++)
			{
				num5 = XXH32_rotl(num5 + (uint)(*ptr * 374761393), 11) * 2654435761u;
			}
			num5 ^= num5 >> 15;
			num5 *= 2246822519u;
			num5 ^= num5 >> 13;
			num5 *= 3266489917u;
			return num5 ^ (num5 >> 16);
		}

		private unsafe static void XXH32_reset(State* state, uint seed)
		{
			XXH.XXH_zero(state, sizeof(State));
			state->v1 = (uint)((int)seed + -1640531535 + -2048144777);
			state->v2 = seed + 2246822519u;
			state->v3 = seed;
			state->v4 = seed - 2654435761u;
		}

		private unsafe static void XXH32_update(State* state, void* input, int len)
		{
			byte* ptr = (byte*)input;
			byte* ptr2 = ptr + len;
			state->total_len_32 += (uint)len;
			state->large_len |= len >= 16 || state->total_len_32 >= 16;
			if (state->memsize + len < 16)
			{
				XXH.XXH_copy((byte*)state->mem32 + state->memsize, input, len);
				state->memsize += (uint)len;
				return;
			}
			if (state->memsize != 0)
			{
				XXH.XXH_copy((byte*)state->mem32 + state->memsize, input, (int)(16 - state->memsize));
				uint* ptr3 = state->mem32;
				state->v1 = XXH32_round(state->v1, XXH.XXH_read32(ptr3));
				state->v2 = XXH32_round(state->v2, XXH.XXH_read32(ptr3 + 1));
				state->v3 = XXH32_round(state->v3, XXH.XXH_read32(ptr3 + 2));
				state->v4 = XXH32_round(state->v4, XXH.XXH_read32(ptr3 + 3));
				ptr += 16 - state->memsize;
				state->memsize = 0u;
			}
			if (ptr <= ptr2 - 16)
			{
				byte* ptr4 = ptr2 - 16;
				uint num = state->v1;
				uint num2 = state->v2;
				uint num3 = state->v3;
				uint num4 = state->v4;
				do
				{
					num = XXH32_round(num, XXH.XXH_read32(ptr));
					num2 = XXH32_round(num2, XXH.XXH_read32(ptr + 4));
					num3 = XXH32_round(num3, XXH.XXH_read32(ptr + 8));
					num4 = XXH32_round(num4, XXH.XXH_read32(ptr + 12));
					ptr += 16;
				}
				while (ptr <= ptr4);
				state->v1 = num;
				state->v2 = num2;
				state->v3 = num3;
				state->v4 = num4;
			}
			if (ptr < ptr2)
			{
				XXH.XXH_copy(state->mem32, ptr, (int)(ptr2 - ptr));
				state->memsize = (uint)(ptr2 - ptr);
			}
		}

		private unsafe static uint XXH32_digest(State* state)
		{
			byte* ptr = (byte*)state->mem32;
			byte* ptr2 = (byte*)state->mem32 + state->memsize;
			uint num = ((!state->large_len) ? (state->v3 + 374761393) : (XXH32_rotl(state->v1, 1) + XXH32_rotl(state->v2, 7) + XXH32_rotl(state->v3, 12) + XXH32_rotl(state->v4, 18)));
			num += state->total_len_32;
			for (; ptr + 4 <= ptr2; ptr += 4)
			{
				num += (uint)((int)XXH.XXH_read32(ptr) * -1028477379);
				num = XXH32_rotl(num, 17) * 668265263;
			}
			for (; ptr < ptr2; ptr++)
			{
				num += (uint)(*ptr * 374761393);
				num = XXH32_rotl(num, 11) * 2654435761u;
			}
			num ^= num >> 15;
			num *= 2246822519u;
			num ^= num >> 13;
			num *= 3266489917u;
			return num ^ (num >> 16);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static uint DigestOf(void* bytes, int length)
		{
			return DigestOf(bytes, length, 0u);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static uint DigestOf(void* bytes, int length, uint seed)
		{
			return XXH32_hash(bytes, length, seed);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static uint DigestOf(ReadOnlySpan<byte> bytes)
		{
			fixed (byte* bytes2 = bytes)
			{
				return DigestOf(bytes2, bytes.Length);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint DigestOf(byte[] bytes, int offset, int length)
		{
			return DigestOf(bytes.AsSpan(offset, length));
		}

		public XXH32()
		{
			Reset();
		}

		public XXH32(uint seed)
		{
			Reset(seed);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Reset()
		{
			Reset(ref _state);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Reset(uint seed)
		{
			Reset(ref _state, seed);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void Update(void* bytes, int length)
		{
			Update(ref _state, bytes, length);
		}

		[Obsolete("Use void* overload")]
		public unsafe void Update(byte* bytes, int length)
		{
			Update(ref _state, bytes, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Update(ReadOnlySpan<byte> bytes)
		{
			Update(ref _state, bytes);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Update(byte[] bytes, int offset, int length)
		{
			Update(ref _state, bytes.AsSpan(offset, length));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public uint Digest()
		{
			return Digest(in _state);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public byte[] DigestBytes()
		{
			return BitConverter.GetBytes(Digest());
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public HashAlgorithm AsHashAlgorithm()
		{
			return new HashAlgorithmAdapter(4, Reset, Update, DigestBytes);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Reset(ref State state, uint seed = 0u)
		{
			fixed (State* state2 = &state)
			{
				XXH32_reset(state2, seed);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Update(ref State state, void* bytes, int length)
		{
			fixed (State* state2 = &state)
			{
				XXH32_update(state2, bytes, length);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Update(ref State state, ReadOnlySpan<byte> bytes)
		{
			fixed (byte* bytes2 = bytes)
			{
				Update(ref state, bytes2, bytes.Length);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static uint Digest(in State state)
		{
			fixed (State* state2 = &state)
			{
				return XXH32_digest(state2);
			}
		}
	}
	public class XXH64 : XXH
	{
		public struct State
		{
			public ulong total_len;

			public ulong v1;

			public ulong v2;

			public ulong v3;

			public ulong v4;

			public unsafe fixed ulong mem64[4];

			public uint memsize;
		}

		private const ulong PRIME64_1 = 11400714785074694791uL;

		private const ulong PRIME64_2 = 14029467366897019727uL;

		private const ulong PRIME64_3 = 1609587929392839161uL;

		private const ulong PRIME64_4 = 9650029242287828579uL;

		private const ulong PRIME64_5 = 2870177450012600261uL;

		public const ulong EmptyHash = 17241709254077376921uL;

		private State _state;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static ulong XXH_rotl64(ulong x, int r)
		{
			return (x << r) | (x >> 64 - r);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static ulong XXH64_round(ulong acc, ulong input)
		{
			return XXH_rotl64(acc + (ulong)((long)input * -4417276706812531889L), 31) * 11400714785074694791uL;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static ulong XXH64_mergeRound(ulong acc, ulong val)
		{
			return (ulong)((long)(acc ^ XXH64_round(0uL, val)) * -7046029288634856825L + -8796714831421723037L);
		}

		private unsafe static ulong XXH64_hash(void* input, int len, ulong seed)
		{
			byte* ptr = (byte*)input;
			byte* ptr2 = ptr + len;
			ulong acc;
			if (len >= 32)
			{
				byte* ptr3 = ptr2 - 32;
				ulong num = (ulong)((long)seed + -7046029288634856825L + -4417276706812531889L);
				ulong num2 = seed + 14029467366897019727uL;
				ulong num3 = seed;
				ulong num4 = seed - 11400714785074694791uL;
				do
				{
					num = XXH64_round(num, XXH.XXH_read64(ptr));
					num2 = XXH64_round(num2, XXH.XXH_read64(ptr + 8));
					num3 = XXH64_round(num3, XXH.XXH_read64(ptr + 16));
					num4 = XXH64_round(num4, XXH.XXH_read64(ptr + 24));
					ptr += 32;
				}
				while (ptr <= ptr3);
				acc = XXH_rotl64(num, 1) + XXH_rotl64(num2, 7) + XXH_rotl64(num3, 12) + XXH_rotl64(num4, 18);
				acc = XXH64_mergeRound(acc, num);
				acc = XXH64_mergeRound(acc, num2);
				acc = XXH64_mergeRound(acc, num3);
				acc = XXH64_mergeRound(acc, num4);
			}
			else
			{
				acc = seed + 2870177450012600261L;
			}
			acc += (ulong)len;
			for (; ptr + 8 <= ptr2; ptr += 8)
			{
				acc ^= XXH64_round(0uL, XXH.XXH_read64(ptr));
				acc = (ulong)((long)XXH_rotl64(acc, 27) * -7046029288634856825L + -8796714831421723037L);
			}
			if (ptr + 4 <= ptr2)
			{
				acc ^= (ulong)(XXH.XXH_read32(ptr) * -7046029288634856825L);
				acc = (ulong)((long)XXH_rotl64(acc, 23) * -4417276706812531889L + 1609587929392839161L);
				ptr += 4;
			}
			for (; ptr < ptr2; ptr++)
			{
				acc ^= (ulong)(*ptr * 2870177450012600261L);
				acc = XXH_rotl64(acc, 11) * 11400714785074694791uL;
			}
			acc ^= acc >> 33;
			acc *= 14029467366897019727uL;
			acc ^= acc >> 29;
			acc *= 1609587929392839161L;
			return acc ^ (acc >> 32);
		}

		private unsafe static void XXH64_reset(State* state, ulong seed)
		{
			XXH.XXH_zero(state, sizeof(State));
			state->v1 = (ulong)((long)seed + -7046029288634856825L + -4417276706812531889L);
			state->v2 = seed + 14029467366897019727uL;
			state->v3 = seed;
			state->v4 = seed - 11400714785074694791uL;
		}

		private unsafe static void XXH64_update(State* state, void* input, int len)
		{
			byte* ptr = (byte*)input;
			byte* ptr2 = ptr + len;
			state->total_len += (ulong)len;
			if (state->memsize + len < 32)
			{
				XXH.XXH_copy((byte*)state->mem64 + state->memsize, input, len);
				state->memsize += (uint)len;
				return;
			}
			if (state->memsize != 0)
			{
				XXH.XXH_copy((byte*)state->mem64 + state->memsize, input, (int)(32 - state->memsize));
				state->v1 = XXH64_round(state->v1, XXH.XXH_read64(state->mem64));
				state->v2 = XXH64_round(state->v2, XXH.XXH_read64(state->mem64 + 1));
				state->v3 = XXH64_round(state->v3, XXH.XXH_read64(state->mem64 + 2));
				state->v4 = XXH64_round(state->v4, XXH.XXH_read64(state->mem64 + 3));
				ptr += 32 - state->memsize;
				state->memsize = 0u;
			}
			if (ptr + 32 <= ptr2)
			{
				byte* ptr3 = ptr2 - 32;
				ulong num = state->v1;
				ulong num2 = state->v2;
				ulong num3 = state->v3;
				ulong num4 = state->v4;
				do
				{
					num = XXH64_round(num, XXH.XXH_read64(ptr));
					num2 = XXH64_round(num2, XXH.XXH_read64(ptr + 8));
					num3 = XXH64_round(num3, XXH.XXH_read64(ptr + 16));
					num4 = XXH64_round(num4, XXH.XXH_read64(ptr + 24));
					ptr += 32;
				}
				while (ptr <= ptr3);
				state->v1 = num;
				state->v2 = num2;
				state->v3 = num3;
				state->v4 = num4;
			}
			if (ptr < ptr2)
			{
				XXH.XXH_copy(state->mem64, ptr, (int)(ptr2 - ptr));
				state->memsize = (uint)(ptr2 - ptr);
			}
		}

		private unsafe static ulong XXH64_digest(State* state)
		{
			byte* ptr = (byte*)state->mem64;
			byte* ptr2 = (byte*)state->mem64 + state->memsize;
			ulong acc;
			if (state->total_len >= 32)
			{
				ulong v = state->v1;
				ulong v2 = state->v2;
				ulong v3 = state->v3;
				ulong v4 = state->v4;
				acc = XXH_rotl64(v, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
				acc = XXH64_mergeRound(acc, v);
				acc = XXH64_mergeRound(acc, v2);
				acc = XXH64_mergeRound(acc, v3);
				acc = XXH64_mergeRound(acc, v4);
			}
			else
			{
				acc = state->v3 + 2870177450012600261L;
			}
			acc += state->total_len;
			for (; ptr + 8 <= ptr2; ptr += 8)
			{
				acc ^= XXH64_round(0uL, XXH.XXH_read64(ptr));
				acc = (ulong)((long)XXH_rotl64(acc, 27) * -7046029288634856825L + -8796714831421723037L);
			}
			if (ptr + 4 <= ptr2)
			{
				acc ^= (ulong)(XXH.XXH_read32(ptr) * -7046029288634856825L);
				acc = (ulong)((long)XXH_rotl64(acc, 23) * -4417276706812531889L + 1609587929392839161L);
				ptr += 4;
			}
			for (; ptr < ptr2; ptr++)
			{
				acc ^= (ulong)(*ptr * 2870177450012600261L);
				acc = XXH_rotl64(acc, 11) * 11400714785074694791uL;
			}
			acc ^= acc >> 33;
			acc *= 14029467366897019727uL;
			acc ^= acc >> 29;
			acc *= 1609587929392839161L;
			return acc ^ (acc >> 32);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static ulong DigestOf(void* bytes, int length)
		{
			return DigestOf(bytes, length, 0uL);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static ulong DigestOf(void* bytes, int length, ulong seed)
		{
			return XXH64_hash(bytes, length, seed);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static ulong DigestOf(ReadOnlySpan<byte> bytes)
		{
			fixed (byte* bytes2 = bytes)
			{
				return DigestOf(bytes2, bytes.Length);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ulong DigestOf(byte[] bytes, int offset, int length)
		{
			return DigestOf(bytes.AsSpan(offset, length));
		}

		public XXH64()
		{
			Reset();
		}

		public XXH64(ulong seed)
		{
			Reset(seed);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Reset()
		{
			Reset(ref _state, 0uL);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Reset(ulong seed)
		{
			Reset(ref _state, seed);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void Update(void* bytes, int length)
		{
			Update(ref _state, bytes, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[Obsolete("Use void* overload, this one will be removed in next version.")]
		public unsafe void Update(byte* bytes, int length)
		{
			Update(ref _state, bytes, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Update(ReadOnlySpan<byte> bytes)
		{
			Update(ref _state, bytes);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Update(byte[] bytes, int offset, int length)
		{
			Update(ref _state, bytes.AsSpan(offset, length));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ulong Digest()
		{
			return Digest(in _state);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public byte[] DigestBytes()
		{
			return BitConverter.GetBytes(Digest());
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public HashAlgorithm AsHashAlgorithm()
		{
			return new HashAlgorithmAdapter(8, Reset, Update, DigestBytes);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Reset(ref State state, ulong seed = 0uL)
		{
			fixed (State* state2 = &state)
			{
				XXH64_reset(state2, seed);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Update(ref State state, void* bytes, int length)
		{
			fixed (State* state2 = &state)
			{
				XXH64_update(state2, bytes, length);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static void Update(ref State state, ReadOnlySpan<byte> bytes)
		{
			fixed (byte* bytes2 = bytes)
			{
				Update(ref state, bytes2, bytes.Length);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static ulong Digest(in State state)
		{
			fixed (State* state2 = &state)
			{
				return XXH64_digest(state2);
			}
		}
	}
}

NebulaModel.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using K4os.Compression.LZ4.Streams;
using Microsoft.CodeAnalysis;
using NebulaAPI;
using NebulaAPI.DataStructures;
using NebulaAPI.GameState;
using NebulaAPI.Interfaces;
using NebulaAPI.Networking;
using NebulaAPI.Packets;
using NebulaModel.Attributes;
using NebulaModel.DataStructures;
using NebulaModel.DataStructures.Chat;
using NebulaModel.Logger;
using NebulaModel.Networking;
using NebulaModel.Networking.Serialization;
using NebulaModel.Utils;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using WebSocketSharp;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("0.9.3.3")]
[assembly: AssemblyInformationalVersion("0.9.3.3+3bb1ae4")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("NebulaModel")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyProduct("NebulaModel")]
[assembly: AssemblyTitle("NebulaModel")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.9.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[GeneratedCode("Nerdbank.GitVersioning.Tasks", "3.6.133.12845")]
[ExcludeFromCodeCoverage]
internal static class ThisAssembly
{
	internal const string AssemblyConfiguration = "Release";

	internal const string AssemblyFileVersion = "0.9.3.3";

	internal const string AssemblyInformationalVersion = "0.9.3.3+3bb1ae4";

	internal const string AssemblyName = "NebulaModel";

	internal const string AssemblyTitle = "NebulaModel";

	internal const string AssemblyVersion = "0.9.3.0";

	internal static readonly DateTime GitCommitDate = new DateTime(638486122650000000L, DateTimeKind.Utc);

	internal const string GitCommitId = "3bb1ae4284b5f16508d9789eff7fcce645bb08ea";

	internal const bool IsPrerelease = false;

	internal const bool IsPublicRelease = true;

	internal const string RootNamespace = "NebulaModel";
}
namespace NebulaModel
{
	public static class Config
	{
		private const string OPTION_SAVE_FILE = "nebula.cfg";

		private const string SECTION_NAME = "Nebula - Settings";

		public static Action OnConfigApplied;

		private static ConfigFile configFile;

		public static PluginInfo ModInfo { get; set; }

		public static string ModVersion => "0.9.3.3+3bb1ae4";

		public static MultiplayerOptions Options { get; set; }

		public static bool LoadOptions()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			Options = new MultiplayerOptions();
			try
			{
				configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "nebula.cfg"), true);
				List<PropertyInfo> declaredProperties = AccessTools.GetDeclaredProperties(typeof(MultiplayerOptions));
				MethodInfo methodInfo = (from m in typeof(ConfigFile).GetMethods()
					where m.Name == "Bind"
					select m).First((MethodInfo m) => m.IsGenericMethod && m.GetParameters().Length == 4);
				foreach (PropertyInfo item in declaredProperties)
				{
					object obj = methodInfo.MakeGenericMethod(item.PropertyType).Invoke(configFile, new object[4]
					{
						"Nebula - Settings",
						item.Name,
						item.GetValue(Options),
						null
					});
					Type type = typeof(ConfigEntry<>).MakeGenericType(item.PropertyType);
					item.SetValue(Options, AccessTools.Property(type, "Value").GetValue(obj));
				}
			}
			catch (Exception ex)
			{
				Log.Error("Could not load nebula.cfg", ex);
				return false;
			}
			return true;
		}

		public static bool SaveOptions()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			try
			{
				List<PropertyInfo> declaredProperties = AccessTools.GetDeclaredProperties(typeof(MultiplayerOptions));
				foreach (PropertyInfo item in declaredProperties)
				{
					ConfigDefinition val = new ConfigDefinition("Nebula - Settings", item.Name);
					configFile[val].BoxedValue = item.GetValue(Options);
				}
				configFile.Save();
			}
			catch (Exception ex)
			{
				Log.Error("Could not load nebula.cfg", ex);
				return false;
			}
			return true;
		}
	}
	[Serializable]
	public class MultiplayerOptions : ICloneable
	{
		private const string _ngrokAuthtokenDisplayname = "Ngrok Authtoken";

		private bool _streamerMode;

		[DisplayName("Nickname")]
		public string Nickname { get; set; } = string.Empty;


		[DisplayName("NameTagSize")]
		public int NameTagSize { get; set; } = 100;


		[DisplayName("Server Password")]
		[Category("Network")]
		[Description("If provided, this will set a password for your hosted server.")]
		[UIContentType(/*Could not decode attribute arguments.*/)]
		public string ServerPassword { get; set; } = string.Empty;


		public string LastClientPassword { get; set; } = string.Empty;


		[DisplayName("Host Port")]
		[Category("Network")]
		[UIRange(1f, 65535f, false)]
		public ushort HostPort { get; set; } = 8469;


		[DisplayName("Enable UPnp/Pmp Support")]
		[Category("Network")]
		[Description("If enabled, attempt to automatically create a port mapping using UPnp/Pmp (only works if your router has this feature and it is enabled)")]
		public bool EnableUPnpOrPmpSupport { get; set; }

		[DisplayName("Enable Experimental Ngrok support")]
		[Category("Network")]
		[Description("If enabled, when hosting a server this will automatically download and install the Ngrok client and set up an Ngrok tunnel that provides an address at which the server can be joined")]
		public bool EnableNgrok { get; set; }

		[DisplayName("Ngrok Authtoken")]
		[Category("Network")]
		[Description("This is required for Ngrok support and can be obtained by creating a free account at https://ngrok.com/")]
		[UICharacterLimit(49)]
		public string NgrokAuthtoken { get; set; } = string.Empty;


		[DisplayName("Ngrok Region")]
		[Category("Network")]
		[Description("Available Regions: us, eu, au, ap, sa, jp, in")]
		public string NgrokRegion { get; set; } = string.Empty;


		[DisplayName("Remember Last IP")]
		[Category("Network")]
		public bool RememberLastIP { get; set; } = true;


		[DisplayName("Remember Last Client Password")]
		[Category("Network")]
		public bool RememberLastClientPassword { get; set; } = true;


		[DisplayName("Enable Discord RPC (requires restart)")]
		[Category("Network")]
		public bool EnableDiscordRPC { get; set; } = true;


		[DisplayName("Auto accept Discord join requests")]
		[Category("Network")]
		public bool AutoAcceptDiscordJoinRequests { get; set; }

		[DisplayName("IP Configuration")]
		[Category("Network")]
		[Description("Configure which type of IP should be used by Discord RPC")]
		public IPUtils.IPConfiguration IPConfiguration { get; set; }

		[DisplayName("Cleanup inactive sessions")]
		[Category("Network")]
		[Description("If disabled the underlying networking library will not cleanup inactive connections. This might solve issues with clients randomly disconnecting and hosts having a 'System.ObjectDisposedException'.")]
		public bool CleanupInactiveSessions { get; set; }

		[DisplayName("Show Lobby Hints")]
		public bool ShowLobbyHints { get; set; } = true;


		public string LastIP { get; set; } = string.Empty;


		[DisplayName("Sync Ups")]
		[Description("If enabled the UPS of each player is synced. This ensures a similar amount of GameTick() calls.")]
		public bool SyncUps { get; set; } = true;


		[DisplayName("Sync Soil")]
		[Description("If enabled the soil count of each players is added together and used as one big pool for everyone. Note that this is a server side setting applied to all clients.")]
		public bool SyncSoil { get; set; }

		[DisplayName("Streamer mode")]
		[Description("If enabled specific personal information like your IP address is hidden from the ingame chat and input fields.")]
		public bool StreamerMode
		{
			get
			{
				return _streamerMode;
			}
			set
			{
				_streamerMode = value;
				GameObject obj = GameObject.Find("list/scroll-view/viewport/content/Network/NgrokAuthtoken");
				InputField inputField = ((obj != null) ? obj.GetComponentInChildren<InputField>() : null);
				UpdateInputFieldContentType(ref inputField);
				GameObject obj2 = GameObject.Find("UI Root/Overlay Canvas/Nebula - Multiplayer Menu/Host IP Address/InputField");
				InputField inputField2 = ((obj2 != null) ? obj2.GetComponentInChildren<InputField>() : null);
				UpdateInputFieldContentType(ref inputField2);
			}
		}

		[DisplayName("Enable Achievement")]
		[Description("Toggle to enable achievement in multiplayer game")]
		public bool EnableAchievement { get; set; } = true;


		[DisplayName("Chat Hotkey")]
		[Category("Chat")]
		[Description("Keyboard shortcut to toggle the chat window")]
		public KeyboardShortcut ChatHotkey { get; set; } = new KeyboardShortcut((KeyCode)96, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 });


		[DisplayName("Auto Open Chat")]
		[Category("Chat")]
		[Description("Auto open chat window when receiving message from other players")]
		public bool AutoOpenChat { get; set; }

		[DisplayName("Show Timestamp")]
		[Category("Chat")]
		public bool EnableTimestamp { get; set; } = true;


		[DisplayName("Show system warn message")]
		[Category("Chat")]
		public bool EnableWarnMessage { get; set; } = true;


		[DisplayName("Show system info message")]
		[Category("Chat")]
		public bool EnableInfoMessage { get; set; } = true;


		[DisplayName("Show battle notification message")]
		[Category("Chat")]
		public bool EnableBattleMessage { get; set; } = true;


		[DisplayName("Default chat position")]
		[Category("Chat")]
		public ChatPosition DefaultChatPosition { get; set; }

		[DisplayName("Default chat size")]
		[Category("Chat")]
		public ChatSize DefaultChatSize { get; set; } = ChatSize.Medium;


		[DisplayName("Notification duration")]
		[Category("Chat")]
		[Description("How long should the active message stay on the screen in seconds")]
		public int NotificationDuration { get; set; } = 15;


		[DisplayName("Chat Window Opacity")]
		[Category("Chat")]
		[UIRange(0f, 1f, true)]
		public float ChatWindowOpacity { get; set; } = 0.8f;


		public bool PowerGridEnabled { get; set; }

		public bool VeinDistributionEnabled { get; set; }

		public bool SpaceNavigationEnabled { get; set; } = true;


		public bool BuildingWarningEnabled { get; set; } = true;


		public bool BuildingIconEnabled { get; set; } = true;


		public bool GuidingLightEnabled { get; set; } = true;


		public bool RemoteAccessEnabled { get; set; }

		public string RemoteAccessPassword { get; set; } = "";


		public bool AutoPauseEnabled { get; set; } = true;


		public object Clone()
		{
			return MemberwiseClone();
		}

		private void UpdateInputFieldContentType(ref InputField inputField)
		{
			if (!((Object)(object)inputField == (Object)null))
			{
				inputField.contentType = (ContentType)(StreamerMode ? 7 : 0);
				inputField.UpdateLabel();
			}
		}

		public void ModifyInputFieldAtCreation(string displayName, ref InputField inputField)
		{
			if (displayName == "Ngrok Authtoken")
			{
				UpdateInputFieldContentType(ref inputField);
			}
		}
	}
	public class NebulaPlayer : INebulaPlayer
	{
		public INebulaConnection Connection { get; set; }

		public IPlayerData Data { get; set; }

		public ushort Id => Data.PlayerId;

		public NebulaPlayer(INebulaConnection connection, IPlayerData data)
		{
			Connection = connection;
			Data = data;
		}

		public void SendPacket<T>(T packet) where T : class, new()
		{
			Connection.SendPacket<T>(packet);
		}

		public void LoadUserData(IPlayerData data)
		{
			ushort id = Id;
			Data = data;
			Data.PlayerId = id;
		}
	}
}
namespace NebulaModel.Utils
{
	public static class AssembliesUtils
	{
		public static IEnumerable<Type> GetTypesWithAttributeInAssembly<T>(Assembly assembly) where T : Attribute
		{
			return from t in assembly.GetTypes()
				where t.GetCustomAttributes(typeof(T), inherit: true).Length != 0
				select t;
		}

		public static IEnumerable<Assembly> GetNebulaAssemblies()
		{
			return from a in AppDomain.CurrentDomain.GetAssemblies()
				where a.FullName.StartsWith("Nebula")
				select a;
		}

		public static Assembly GetAssemblyByName(string name)
		{
			return AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.FullName.StartsWith(name + "."));
		}
	}
	public static class ChatUtils
	{
		private const float ReferenceX = 1920f;

		private const float ReferenceY = 1080f;

		private static readonly string[] AllowedTags = new string[11]
		{
			"b", "i", "s", "u", "indent", "link", "mark", "sprite", "sub", "sup",
			"color"
		};

		private static readonly Vector2[] ChatMargins = (Vector2[])(object)new Vector2[4]
		{
			new Vector2(10f, 350f),
			new Vector2(10f, 350f),
			new Vector2(10f, 10f),
			new Vector2(10f, 100f)
		};

		private static readonly Vector2[] ChatSizes = (Vector2[])(object)new Vector2[3]
		{
			new Vector2(500f, 300f),
			new Vector2(700f, 420f),
			new Vector2(800f, 480f)
		};

		public static Vector2 GetDefaultPosition(ChatPosition position, ChatSize size)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			Vector2 defaultSize = GetDefaultSize(size);
			Vector2 val = ChatMargins[(int)position];
			bool flag = (position & ChatPosition.RightMiddle) == ChatPosition.RightMiddle;
			bool flag2 = (position & ChatPosition.LeftTop) == ChatPosition.LeftTop;
			float num = ((!flag) ? val.x : (1920f - val.x - defaultSize.x));
			float num2 = ((!flag2) ? (-1080f + val.y + defaultSize.y) : (0f - val.y));
			num *= (float)Screen.width / 1920f;
			num2 *= (float)Screen.height / 1080f;
			return new Vector2(num, num2);
		}

		public static Vector2 GetDefaultSize(ChatSize size)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			Vector2 result = ChatSizes[(int)size];
			result.x *= (float)Screen.width / 1920f;
			result.y *= (float)Screen.height / 1080f;
			return result;
		}

		public static string SanitizeText(string input)
		{
			Regex regex = new Regex("<([/\\w]+)=?[\"#]?\\w*\"?\\s?[\\s\\w\"=]*>");
			return regex.Replace(input, delegate(Match match)
			{
				string value = match.Groups[1].Value;
				return (AllowedTags.Contains(value) || AllowedTags.Contains(value.Substring(1))) ? match.Value : "";
			});
		}

		public static Color GetMessageColor(ChatMessageType messageType)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			switch (messageType)
			{
			case ChatMessageType.PlayerMessage:
				return Color.white;
			case ChatMessageType.SystemInfoMessage:
				return Color.cyan;
			case ChatMessageType.SystemWarnMessage:
				return new Color(1f, 0.95f, 0f, 1f);
			case ChatMessageType.BattleMessage:
				return Color.cyan;
			case ChatMessageType.CommandUsageMessage:
				return new Color(1f, 0.65f, 0f, 1f);
			case ChatMessageType.CommandOutputMessage:
				return new Color(0.8f, 0.8f, 0.8f, 1f);
			case ChatMessageType.CommandErrorMessage:
				return Color.red;
			case ChatMessageType.PlayerMessagePrivate:
				return Color.green;
			default:
				Console.WriteLine($"Requested color for unexpected chat message type {messageType}");
				return Color.white;
			}
		}

		public static bool IsCommandMessage(this ChatMessageType type)
		{
			if ((uint)(type - 1) <= 1u || (uint)(type - 4) <= 2u)
			{
				return true;
			}
			return false;
		}

		public static bool Contains(this string source, string toCheck, StringComparison comp)
		{
			if (source == null)
			{
				return false;
			}
			return source.IndexOf(toCheck, comp) >= 0;
		}

		public static void Insert(this TMP_InputField field, string str)
		{
			if (!field.m_ReadOnly)
			{
				field.Delete();
				if (field.characterLimit <= 0 || field.text.Length < field.characterLimit)
				{
					field.text = field.text.Insert(field.m_StringPosition, str);
					int stringSelectPositionInternal = (field.stringPositionInternal += str.Length);
					field.stringSelectPositionInternal = stringSelectPositionInternal;
					field.UpdateTouchKeyboardFromEditChanges();
					field.SendOnValueChanged();
				}
			}
		}
	}
	public class ChildProcessLinker
	{
		private enum DebugEventType
		{
			CREATE_PROCESS_DEBUG_EVENT = 3,
			CREATE_THREAD_DEBUG_EVENT = 2,
			EXCEPTION_DEBUG_EVENT = 1,
			EXIT_PROCESS_DEBUG_EVENT = 5,
			EXIT_THREAD_DEBUG_EVENT = 4,
			LOAD_DLL_DEBUG_EVENT = 6,
			OUTPUT_DEBUG_STRING_EVENT = 8,
			RIP_EVENT = 9,
			UNLOAD_DLL_DEBUG_EVENT = 7
		}

		private struct DEBUG_EVENT
		{
			[MarshalAs(UnmanagedType.I4)]
			public DebugEventType dwDebugEventCode;

			public int dwProcessId;

			public int dwThreadId;

			[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
			public byte[] bytes;
		}

		private readonly Action<Exception> _safeNullDebuggerExceptionHandler;

		private const int DBG_CONTINUE = 65538;

		private const int DBG_EXCEPTION_NOT_HANDLED = -2147418111;

		private Process ChildProcess { get; set; }

		public ChildProcessLinker(Process childProcess, Action<Exception> exceptionHandler = null)
		{
			ChildProcess = childProcess;
			_safeNullDebuggerExceptionHandler = exceptionHandler;
			Thread thread = new Thread((_safeNullDebuggerExceptionHandler != null) ? new ParameterizedThreadStart(SafeNullDebugger) : new ParameterizedThreadStart(NullDebugger));
			thread.IsBackground = true;
			thread.Start(ChildProcess.Id);
		}

		private void NullDebugger(object arg)
		{
			if (DebugActiveProcess((int)arg))
			{
				while (!ChildProcess.HasExited)
				{
					if (WaitForDebugEvent(out var lpDebugEvent, 1000))
					{
						int dwContinueStatus = 65538;
						if (lpDebugEvent.dwDebugEventCode == DebugEventType.EXCEPTION_DEBUG_EVENT)
						{
							dwContinueStatus = -2147418111;
						}
						ContinueDebugEvent(lpDebugEvent.dwProcessId, lpDebugEvent.dwThreadId, dwContinueStatus);
					}
				}
				return;
			}
			throw new Exception("ChildProcessLinker was unable to attach NullDebugger!");
		}

		private void SafeNullDebugger(object arg)
		{
			try
			{
				NullDebugger(arg);
			}
			catch (Exception obj)
			{
				_safeNullDebuggerExceptionHandler(obj);
			}
		}

		[DllImport("Kernel32.dll", SetLastError = true)]
		private static extern bool DebugActiveProcess(int dwProcessId);

		[DllImport("Kernel32.dll", SetLastError = true)]
		private static extern bool WaitForDebugEvent(out DEBUG_EVENT lpDebugEvent, int dwMilliseconds);

		[DllImport("Kernel32.dll", SetLastError = true)]
		private static extern bool ContinueDebugEvent(int dwProcessId, int dwThreadId, int dwContinueStatus);

		[DllImport("Kernel32.dll", SetLastError = true)]
		private static extern bool IsDebuggerPresent();
	}
	public static class CryptoUtils
	{
		private static readonly string docPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);

		private static readonly string dataPath = Path.Combine(docPath, GameConfig.gameName);

		private static readonly string keyFile = Path.Combine(docPath, dataPath, "player.key");

		private static readonly string dataPath2 = Path.Combine(GameConfig.gameName);

		private static readonly string keyFile2 = Path.Combine(dataPath2, "player.key");

		public static RSA GetOrCreateUserCert()
		{
			if (string.IsNullOrEmpty(docPath))
			{
				Log.Warn("Could not find documents folder! Using game directory.");
				try
				{
					Directory.CreateDirectory(dataPath);
				}
				catch
				{
					Log.Error("Unable to create directory " + dataPath + ", permission denied.");
					throw;
				}
			}
			RSA rSA = RSA.Create();
			if (File.Exists(keyFile))
			{
				rSA.FromXmlString(File.ReadAllText(keyFile));
			}
			else if (File.Exists(keyFile2))
			{
				rSA.FromXmlString(File.ReadAllText(keyFile2));
			}
			else
			{
				try
				{
					Log.Info("Store player key in " + keyFile);
					File.WriteAllText(keyFile, rSA.ToXmlString(includePrivateParameters: true));
				}
				catch (Exception ex)
				{
					Log.Warn($"Unable to write to default path, reason: {ex.GetType()}");
					if (!Directory.Exists(dataPath2))
					{
						Log.Info("Create directory " + dataPath2);
						Directory.CreateDirectory(dataPath2);
					}
					Log.Info("Store player key in " + keyFile2);
					File.WriteAllText(keyFile2, rSA.ToXmlString(includePrivateParameters: true));
				}
			}
			return rSA;
		}

		public static byte[] GetPublicKey(RSA rsa)
		{
			return Convert.FromBase64String(rsa.ToXmlString(includePrivateParameters: false).Substring(22, 172));
		}

		public static string Hash(byte[] input)
		{
			byte[] inArray = new SHA1Managed().ComputeHash(input);
			return Convert.ToBase64String(inArray);
		}

		public static string Hash(string input)
		{
			byte[] inArray = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(input));
			return Convert.ToBase64String(inArray);
		}

		public static string GetCurrentUserPublicKeyHash()
		{
			return Hash(GetPublicKey(GetOrCreateUserCert()));
		}

		public static string ToBase64(this string s)
		{
			byte[] bytes = Encoding.UTF8.GetBytes(s);
			return Convert.ToBase64String(bytes);
		}

		public static string FromBase64(this string s)
		{
			byte[] bytes = Convert.FromBase64String(s);
			return Encoding.UTF8.GetString(bytes);
		}
	}
	public static class IPUtils
	{
		public enum DataState
		{
			Unset,
			Fresh,
			Cached
		}

		public enum IPConfiguration
		{
			Both,
			IPv4,
			IPv6
		}

		private enum PortStatus
		{
			Open,
			Closed
		}

		private enum Status
		{
			None,
			Unsupported,
			Unavailable
		}

		public struct IpInfo
		{
			public string LANAddress;

			public string WANv4Address;

			public string WANv6Address;

			public string PortStatus;

			public DataState DataState;
		}

		private static readonly HttpClient client;

		private static IpInfo ipInfo;

		private static readonly System.Timers.Timer timer;

		static IPUtils()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			client = new HttpClient();
			timer = new System.Timers.Timer
			{
				Enabled = false,
				Interval = TimeSpan.FromMinutes(1.0).TotalMilliseconds
			};
			timer.Elapsed += delegate
			{
				timer.Stop();
			};
			client.Timeout = TimeSpan.FromSeconds(15.0);
		}

		private static string GetLocalAddress()
		{
			using Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.IP);
			socket.Connect("8.8.8.8", 65530);
			if (socket.LocalEndPoint is IPEndPoint iPEndPoint)
			{
				return iPEndPoint.Address.ToString();
			}
			return string.Empty;
		}

		public static async Task<string> GetWANv4Address()
		{
			try
			{
				string text = await client.GetStringAsync("https://api.ipify.org");
				return IsIPv4(text) ? text : Status.Unsupported.ToString();
			}
			catch (Exception message)
			{
				Log.Warn(message);
				return ipInfo.WANv4Address ?? Status.Unavailable.ToString();
			}
		}

		public static async Task<string> GetWANv6Address()
		{
			try
			{
				string text = await client.GetStringAsync("https://api64.ipify.org");
				return IsIPv6(text) ? ("[" + text + "]") : Status.Unsupported.ToString();
			}
			catch (Exception message)
			{
				Log.Warn(message);
				return ipInfo.WANv6Address ?? Status.Unavailable.ToString();
			}
		}

		private static async Task<string> GetPortStatus(ushort port)
		{
			_ = 3;
			try
			{
				string response = await client.GetStringAsync($"https://ifconfig.co/port/{port}");
				Dictionary<string, object> dictionary = MiniJson.Deserialize(response) as Dictionary<string, object>;
				if (dictionary != null && IsIPv4((string)dictionary["ip"]))
				{
					return ((bool)dictionary["reachable"]) ? PortStatus.Open.ToString() : (PortStatus.Closed.ToString() + "(IPv4)");
				}
				string result = ((dictionary != null && (bool)dictionary["reachable"]) ? PortStatus.Open.ToString() : PortStatus.Closed.ToString()) + "(IPv6) ";
				try
				{
					IPAddress iPv4Address = (from ip in (await Dns.GetHostEntryAsync(string.Empty)).AddressList
						where ip.AddressFamily == AddressFamily.InterNetwork
						select new
						{
							ip = ip,
							str = ip.ToString()
						} into t
						where !t.str.StartsWith("127.0") && !t.str.StartsWith("192.168")
						select t.ip).FirstOrDefault();
					if (iPv4Address != null)
					{
						if (WebRequest.Create($"https://ifconfig.co/port/{port}") is HttpWebRequest httpWebRequest)
						{
							httpWebRequest.Timeout = 5000;
							httpWebRequest.ServicePoint.BindIPEndPointDelegate = (ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount) => new IPEndPoint(iPv4Address, 0);
							using WebResponse webResponse = await httpWebRequest.GetResponseAsync();
							using Stream stream = webResponse.GetResponseStream();
							if (stream != null)
							{
								using StreamReader readStream = new StreamReader(stream, Encoding.UTF8);
								response = await readStream.ReadToEndAsync();
							}
						}
						dictionary = MiniJson.Deserialize(response) as Dictionary<string, object>;
						result = result + ((dictionary != null && (bool)dictionary["reachable"]) ? PortStatus.Open.ToString() : PortStatus.Closed.ToString()) + "(IPv4)";
					}
				}
				catch (Exception message)
				{
					Log.Warn(message);
				}
				return result;
			}
			catch (Exception message2)
			{
				Log.Warn(message2);
				return ipInfo.PortStatus ?? Status.Unavailable.ToString();
			}
		}

		public static async Task<IpInfo> GetIPInfo(ushort port = 0)
		{
			if (timer.Enabled && IPUtils.ipInfo.DataState != 0)
			{
				return IPUtils.ipInfo;
			}
			IpInfo ipInfo = default(IpInfo);
			ipInfo.LANAddress = GetLocalAddress();
			ipInfo.WANv4Address = await GetWANv4Address();
			ipInfo.WANv6Address = await GetWANv6Address();
			ipInfo.DataState = DataState.Fresh;
			ipInfo.PortStatus = await GetPortStatus(port);
			IpInfo result = (IPUtils.ipInfo = ipInfo);
			IPUtils.ipInfo.DataState = DataState.Cached;
			timer.Start();
			return result;
		}

		public static bool IsIPv6(string ip)
		{
			if (IPAddress.TryParse(ip, out IPAddress address))
			{
				return address.AddressFamily == AddressFamily.InterNetworkV6;
			}
			return false;
		}

		public static bool IsIPv4(string ip)
		{
			if (IPAddress.TryParse(ip, out IPAddress address))
			{
				return address.AddressFamily == AddressFamily.InterNetwork;
			}
			return false;
		}

		public static async Task<bool> IsIPv6Supported()
		{
			return IsIPv6(await GetWANv6Address());
		}
	}
	public static class NativeInterop
	{
		private delegate bool CtrlHandler(CtrlType sig);

		private enum CtrlType
		{
			CTRL_C_EVENT = 0,
			CTRL_BREAK_EVENT = 1,
			CTRL_CLOSE_EVENT = 2,
			CTRL_LOGOFF_EVENT = 5,
			CTRL_SHUTDOWN_EVENT = 6
		}

		private const int SW_HIDE = 0;

		[DllImport("user32.dll")]
		private static extern IntPtr GetActiveWindow();

		[DllImport("user32.dll")]
		private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

		public static void HideWindow()
		{
			ShowWindow(GetActiveWindow(), 0);
		}

		[DllImport("Kernel32")]
		private static extern bool SetConsoleCtrlHandler(CtrlHandler handler, bool add);

		private static bool Handler(CtrlType sig)
		{
			Console.WriteLine($"Exiting app due to {sig}");
			switch (sig)
			{
			case CtrlType.CTRL_C_EVENT:
			case CtrlType.CTRL_BREAK_EVENT:
			{
				Console.WriteLine("Start saving to last exit...");
				ManualResetEvent mre = new ManualResetEvent(initialState: false);
				ThreadingHelper.Instance.StartSyncInvoke((Action)delegate
				{
					UIRoot.instance.uiGame.escMenu.OnButton6Click();
					mre.Set();
				});
				mre.WaitOne();
				Console.WriteLine("Saving completed!");
				Thread.Sleep(1000);
				return false;
			}
			default:
				throw new ArgumentOutOfRangeException("sig", "Unknown CtrlType: " + sig);
			case CtrlType.CTRL_CLOSE_EVENT:
			case CtrlType.CTRL_LOGOFF_EVENT:
			case CtrlType.CTRL_SHUTDOWN_EVENT:
				Thread.Sleep(500);
				return false;
			}
		}

		public static void SetConsoleCtrlHandler()
		{
			bool flag = SetConsoleCtrlHandler(Handler, add: true);
			Console.WriteLine("SetConsoleCtrlHandler: " + (flag ? "Success" : "Fail"));
		}
	}
	public static class ProtoUtils
	{
		public static string GetSignalDisplayName(int signalId)
		{
			if (signalId < 20000)
			{
				if (signalId < 1000)
				{
					SignalProto val = ((ProtoSet<SignalProto>)(object)LDB.signals).Select(signalId);
					return ((Proto)val).name;
				}
				ItemProto val2 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(signalId);
				return ((Proto)val2).name;
			}
			if (signalId < 40000)
			{
				RecipeProto val3 = ((ProtoSet<RecipeProto>)(object)LDB.recipes).Select(signalId - 20000);
				return ((Proto)val3).name;
			}
			TechProto val4 = ((ProtoSet<TechProto>)(object)LDB.techs).Select(signalId - 40000);
			return ((Proto)val4).name;
		}
	}
	public static class MiniJson
	{
		private sealed class Parser : IDisposable
		{
			private enum TOKEN
			{
				NONE,
				CURLY_OPEN,
				CURLY_CLOSE,
				SQUARED_OPEN,
				SQUARED_CLOSE,
				COLON,
				COMMA,
				STRING,
				NUMBER,
				TRUE,
				FALSE,
				NULL
			}

			private const string WORD_BREAK = "{}[],:\"";

			private StringReader json;

			private char PeekChar => Convert.ToChar(json.Peek());

			private char NextChar => Convert.ToChar(json.Read());

			private string NextWord
			{
				get
				{
					StringBuilder stringBuilder = new StringBuilder();
					while (!IsWordBreak(PeekChar))
					{
						stringBuilder.Append(NextChar);
						if (json.Peek() == -1)
						{
							break;
						}
					}
					return stringBuilder.ToString();
				}
			}

			private TOKEN NextToken
			{
				get
				{
					EatWhitespace();
					if (json.Peek() == -1)
					{
						return TOKEN.NONE;
					}
					switch (PeekChar)
					{
					case '{':
						return TOKEN.CURLY_OPEN;
					case '}':
						json.Read();
						return TOKEN.CURLY_CLOSE;
					case '[':
						return TOKEN.SQUARED_OPEN;
					case ']':
						json.Read();
						return TOKEN.SQUARED_CLOSE;
					case ',':
						json.Read();
						return TOKEN.COMMA;
					case '"':
						return TOKEN.STRING;
					case ':':
						return TOKEN.COLON;
					case '-':
					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
					case '8':
					case '9':
						return TOKEN.NUMBER;
					default:
						return NextWord switch
						{
							"false" => TOKEN.FALSE, 
							"true" => TOKEN.TRUE, 
							"null" => TOKEN.NULL, 
							_ => TOKEN.NONE, 
						};
					}
				}
			}

			private Parser(string jsonString)
			{
				json = new StringReader(jsonString);
			}

			public void Dispose()
			{
				json.Dispose();
				json = null;
			}

			private static bool IsWordBreak(char c)
			{
				if (!char.IsWhiteSpace(c))
				{
					return "{}[],:\"".IndexOf(c) != -1;
				}
				return true;
			}

			public static object Parse(string jsonString)
			{
				using Parser parser = new Parser(jsonString);
				return parser.ParseValue();
			}

			private Dictionary<string, object> ParseObject()
			{
				Dictionary<string, object> dictionary = new Dictionary<string, object>();
				json.Read();
				while (true)
				{
					switch (NextToken)
					{
					case TOKEN.COMMA:
						continue;
					case TOKEN.NONE:
						return null;
					case TOKEN.CURLY_CLOSE:
						return dictionary;
					}
					string text = ParseString();
					if (text == null)
					{
						return null;
					}
					if (NextToken != TOKEN.COLON)
					{
						return null;
					}
					json.Read();
					dictionary[text] = ParseValue();
				}
			}

			private List<object> ParseArray()
			{
				List<object> list = new List<object>();
				json.Read();
				bool flag = true;
				while (flag)
				{
					TOKEN nextToken = NextToken;
					switch (nextToken)
					{
					case TOKEN.NONE:
						return null;
					case TOKEN.SQUARED_CLOSE:
						flag = false;
						break;
					default:
					{
						object item = ParseByToken(nextToken);
						list.Add(item);
						break;
					}
					case TOKEN.COMMA:
						break;
					}
				}
				return list;
			}

			private object ParseValue()
			{
				TOKEN nextToken = NextToken;
				return ParseByToken(nextToken);
			}

			private object ParseByToken(TOKEN token)
			{
				return token switch
				{
					TOKEN.STRING => ParseString(), 
					TOKEN.NUMBER => ParseNumber(), 
					TOKEN.CURLY_OPEN => ParseObject(), 
					TOKEN.SQUARED_OPEN => ParseArray(), 
					TOKEN.TRUE => true, 
					TOKEN.FALSE => false, 
					TOKEN.NULL => null, 
					_ => null, 
				};
			}

			private string ParseString()
			{
				StringBuilder stringBuilder = new StringBuilder();
				json.Read();
				bool flag = true;
				while (flag && json.Peek() != -1)
				{
					char nextChar = NextChar;
					switch (nextChar)
					{
					case '"':
						flag = false;
						break;
					case '\\':
						if (json.Peek() == -1)
						{
							flag = false;
							break;
						}
						nextChar = NextChar;
						switch (nextChar)
						{
						case '"':
						case '/':
						case '\\':
							stringBuilder.Append(nextChar);
							break;
						case 'b':
							stringBuilder.Append('\b');
							break;
						case 'f':
							stringBuilder.Append('\f');
							break;
						case 'n':
							stringBuilder.Append('\n');
							break;
						case 'r':
							stringBuilder.Append('\r');
							break;
						case 't':
							stringBuilder.Append('\t');
							break;
						case 'u':
						{
							char[] array = new char[4];
							for (int i = 0; i < 4; i++)
							{
								array[i] = NextChar;
							}
							stringBuilder.Append((char)Convert.ToInt32(new string(array), 16));
							break;
						}
						}
						break;
					default:
						stringBuilder.Append(nextChar);
						break;
					}
				}
				return stringBuilder.ToString();
			}

			private object ParseNumber()
			{
				string nextWord = NextWord;
				if (nextWord.IndexOf('.') == -1 && long.TryParse(nextWord, out var result))
				{
					return result;
				}
				if (double.TryParse(nextWord, out var result2))
				{
					return result2;
				}
				return null;
			}

			private void EatWhitespace()
			{
				while (char.IsWhiteSpace(PeekChar))
				{
					json.Read();
					if (json.Peek() == -1)
					{
						break;
					}
				}
			}
		}

		private sealed class Serializer
		{
			private readonly StringBuilder builder;

			private Serializer()
			{
				builder = new StringBuilder();
			}

			public static string Serialize(object obj)
			{
				Serializer serializer = new Serializer();
				serializer.SerializeValue(obj);
				return serializer.builder.ToString();
			}

			private void SerializeValue(object value)
			{
				if (value == null)
				{
					builder.Append("null");
				}
				else if (value is string str)
				{
					SerializeString(str);
				}
				else if (value is bool flag)
				{
					builder.Append(flag ? "true" : "false");
				}
				else if (value is IList anArray)
				{
					SerializeArray(anArray);
				}
				else if (value is IDictionary obj)
				{
					SerializeObject(obj);
				}
				else if (value is char c)
				{
					SerializeString(new string(c, 1));
				}
				else
				{
					SerializeOther(value);
				}
			}

			private void SerializeObject(IDictionary obj)
			{
				bool flag = true;
				builder.Append('{');
				foreach (object key in obj.Keys)
				{
					if (!flag)
					{
						builder.Append(',');
					}
					SerializeString(key.ToString());
					builder.Append(':');
					SerializeValue(obj[key]);
					flag = false;
				}
				builder.Append('}');
			}

			private void SerializeArray(IEnumerable anArray)
			{
				builder.Append('[');
				bool flag = true;
				foreach (object item in anArray)
				{
					if (!flag)
					{
						builder.Append(',');
					}
					SerializeValue(item);
					flag = false;
				}
				builder.Append(']');
			}

			private void SerializeString(string str)
			{
				builder.Append('"');
				char[] array = str.ToCharArray();
				char[] array2 = array;
				foreach (char c in array2)
				{
					switch (c)
					{
					case '"':
						builder.Append("\\\"");
						continue;
					case '\\':
						builder.Append("\\\\");
						continue;
					case '\b':
						builder.Append("\\b");
						continue;
					case '\f':
						builder.Append("\\f");
						continue;
					case '\n':
						builder.Append("\\n");
						continue;
					case '\r':
						builder.Append("\\r");
						continue;
					case '\t':
						builder.Append("\\t");
						continue;
					}
					int num = Convert.ToInt32(c);
					if (num >= 32 && num <= 126)
					{
						builder.Append(c);
						continue;
					}
					builder.Append("\\u");
					builder.Append(num.ToString("x4"));
				}
				builder.Append('"');
			}

			private void SerializeOther(object value)
			{
				if (!(value is float num))
				{
					if (!(value is int) && !(value is uint) && !(value is long) && !(value is sbyte) && !(value is byte) && !(value is short) && !(value is ushort) && !(value is ulong))
					{
						if (value is double || value is decimal)
						{
							builder.Append(Convert.ToDouble(value).ToString("R"));
						}
						else
						{
							SerializeString(value.ToString());
						}
					}
					else
					{
						builder.Append(value);
					}
				}
				else
				{
					builder.Append(num.ToString("R"));
				}
			}
		}

		public static object Deserialize(string json)
		{
			if (json != null)
			{
				return Parser.Parse(json);
			}
			return null;
		}

		public static string Serialize(object obj)
		{
			return Serializer.Serialize(obj);
		}
	}
	public class TimeUtils
	{
		private static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

		public static long CurrentUnixTimestampMilliseconds()
		{
			return (long)(DateTime.UtcNow - UNIX_EPOCH).TotalMilliseconds;
		}
	}
	public class UnityDispatchQueue : MonoBehaviour
	{
		private static UnityDispatchQueue _instance;

		private readonly Queue<Action> actionsQueue = new Queue<Action>();

		private void Update()
		{
			lock (actionsQueue)
			{
				while (actionsQueue.Count > 0)
				{
					actionsQueue.Dequeue()();
				}
			}
		}

		private void OnDestroy()
		{
			_instance = null;
		}

		private static UnityDispatchQueue GetInstance()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_instance))
			{
				_instance = Object.FindObjectOfType<UnityDispatchQueue>();
			}
			if (Object.op_Implicit((Object)(object)_instance))
			{
				return _instance;
			}
			GameObject val = new GameObject("UnityDispatchQueue");
			_instance = val.AddComponent<UnityDispatchQueue>();
			Object.DontDestroyOnLoad((Object)(object)_instance);
			return _instance;
		}

		public static void RunOnMainThread(Action action)
		{
			UnityDispatchQueue instance = GetInstance();
			lock (instance.actionsQueue)
			{
				instance.actionsQueue.Enqueue(action);
			}
		}
	}
}
namespace NebulaModel.Packets.Warning
{
	public class WarningDataPacket
	{
		public int ActiveWarningCount { get; set; }

		public int Tick { get; set; }

		public byte[] BinaryData { get; set; }
	}
	public class WarningDataRequest
	{
		public WarningRequestEvent Event { get; set; }

		public WarningDataRequest()
		{
		}

		public WarningDataRequest(WarningRequestEvent requestEvent)
		{
			Event = requestEvent;
		}
	}
	public enum WarningRequestEvent
	{
		Signal,
		Data
	}
	public class WarningSignalPacket
	{
		public int SignalCount { get; set; }

		public int[] Signals { get; set; }

		public int[] Counts { get; set; }

		public int Tick { get; set; }
	}
}
namespace NebulaModel.Packets.Universe
{
	[HidePacketInDebugLogs]
	public class DysonLaunchDataPacket
	{
		public DysonLaunchData Data { get; set; }

		public DysonLaunchDataPacket()
		{
		}

		public DysonLaunchDataPacket(DysonLaunchData data)
		{
			Data = data;
		}
	}
	public class DysonSailDataPacket
	{
		public int StarIndex { get; set; }

		public int OrbitId { get; set; }

		public long ExpiryTime { get; set; }

		public float st { get; set; }

		public float px { get; set; }

		public float py { get; set; }

		public float pz { get; set; }

		public float vx { get; set; }

		public float vy { get; set; }

		public float vz { get; set; }

		public float gs { get; set; }

		public DysonSailDataPacket()
		{
		}

		public DysonSailDataPacket(int starIndex, ref DysonSail sail, int orbitId, long expiryTime)
		{
			StarIndex = starIndex;
			OrbitId = orbitId;
			ExpiryTime = expiryTime;
			st = sail.st;
			px = sail.px;
			py = sail.py;
			pz = sail.pz;
			vx = sail.vx;
			vy = sail.vy;
			vz = sail.vz;
			gs = sail.gs;
		}
	}
	public class DysonSphereData
	{
		public int StarIndex { get; set; }

		public byte[] BinaryData { get; set; }

		public DysonSphereRespondEvent Event { get; set; }

		public DysonSphereData()
		{
		}

		public DysonSphereData(int starIndex, byte[] data, DysonSphereRespondEvent respondEvent)
		{
			StarIndex = starIndex;
			BinaryData = data;
			Event = respondEvent;
		}
	}
	public enum DysonSphereRespondEvent
	{
		List = 1,
		Load,
		Desync
	}
	public class DysonSphereLoadRequest
	{
		public int StarIndex { get; set; }

		public DysonSphereRequestEvent Event { get; set; }

		public DysonSphereLoadRequest()
		{
		}

		public DysonSphereLoadRequest(int starIndex, DysonSphereRequestEvent requestEvent)
		{
			StarIndex = starIndex;
			Event = requestEvent;
		}
	}
	public enum DysonSphereRequestEvent
	{
		List = 1,
		Load,
		Unload,
		Query
	}
	[HidePacketInDebugLogs]
	public class DysonSphereStatusPacket
	{
		public int StarIndex { get; set; }

		public float GrossRadius { get; set; }

		public long EnergyReqCurrentTick { get; set; }

		public long EnergyGenCurrentTick { get; set; }

		public DysonSphereStatusPacket()
		{
		}

		public DysonSphereStatusPacket(DysonSphere dysonSphere)
		{
			StarIndex = dysonSphere.starData.index;
			GrossRadius = dysonSphere.grossRadius;
			EnergyReqCurrentTick = dysonSphere.energyReqCurrentTick;
			EnergyGenCurrentTick = dysonSphere.energyGenCurrentTick;
		}
	}
	public class NameInputPacket
	{
		public string[] Names { get; set; }

		public int[] PlanetIds { get; set; }

		public int[] StarIds { get; set; }

		public NameInputPacket()
		{
		}

		public NameInputPacket(string name, int starId, int planetId)
		{
			Names = new string[1] { name };
			StarIds = new int[1] { starId };
			PlanetIds = new int[1] { planetId };
		}

		public NameInputPacket(in GalaxyData galaxy)
		{
			List<string> list = new List<string>();
			List<int> list2 = new List<int>();
			List<int> list3 = new List<int>();
			StarData[] stars = galaxy.stars;
			foreach (StarData val in stars)
			{
				if (!string.IsNullOrEmpty(val.overrideName))
				{
					list.Add(val.overrideName);
					list2.Add(val.id);
					list3.Add(-2);
				}
				PlanetData[] planets = val.planets;
				foreach (PlanetData val2 in planets)
				{
					if (!string.IsNullOrEmpty(val2.overrideName))
					{
						list.Add(val2.overrideName);
						list2.Add(-1);
						list3.Add(val2.id);
					}
				}
			}
			Names = list.ToArray();
			StarIds = list2.ToArray();
			PlanetIds = list3.ToArray();
		}
	}
}
namespace NebulaModel.Packets.Universe.Editor
{
	public class DysonBlueprintPacket
	{
		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public EDysonBlueprintType BlueprintType { get; set; }

		public byte[] BinaryData { get; set; }

		public DysonBlueprintPacket()
		{
		}

		public DysonBlueprintPacket(int starIndex, int layerId, EDysonBlueprintType blueprintType, string stringData)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			StarIndex = starIndex;
			LayerId = layerId;
			BlueprintType = blueprintType;
			BinaryData = Encoding.ASCII.GetBytes(stringData);
		}
	}
	public class DysonSphereAddFramePacket
	{
		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public int FrameId { get; set; }

		public int ProtoId { get; set; }

		public int NodeAId { get; set; }

		public int NodeBId { get; set; }

		public bool Euler { get; set; }

		public DysonSphereAddFramePacket()
		{
		}

		public DysonSphereAddFramePacket(int starIndex, int layerId, int frameId, int protoId, int nodeAId, int nodeBId, bool euler)
		{
			StarIndex = starIndex;
			LayerId = layerId;
			FrameId = frameId;
			ProtoId = protoId;
			NodeAId = nodeAId;
			NodeBId = nodeBId;
			Euler = euler;
		}
	}
	public class DysonSphereAddLayerPacket
	{
		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public float OrbitRadius { get; set; }

		public Float4 OrbitRotation { get; set; }

		public float OrbitAngularSpeed { get; set; }

		public DysonSphereAddLayerPacket()
		{
		}

		public DysonSphereAddLayerPacket(int starIndex, int layerId, float orbitRadius, Quaternion orbitRotation, float orbitAngularSpeed)
		{
			//IL_001c: 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)
			StarIndex = starIndex;
			LayerId = layerId;
			OrbitRadius = orbitRadius;
			OrbitRotation = new Float4(orbitRotation);
			OrbitAngularSpeed = orbitAngularSpeed;
		}
	}
	public class DysonSphereAddNodePacket
	{
		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public int NodeId { get; set; }

		public int NodeProtoId { get; set; }

		public Float3 Position { get; set; }

		public DysonSphereAddNodePacket()
		{
		}

		public DysonSphereAddNodePacket(int starIndex, int layerId, int nodeId, int nodeProtoId, Float3 position)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			StarIndex = starIndex;
			LayerId = layerId;
			NodeId = nodeId;
			NodeProtoId = nodeProtoId;
			Position = position;
		}
	}
	public class DysonSphereAddShellPacket
	{
		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public int ShellId { get; set; }

		public int ProtoId { get; set; }

		public int[] NodeIds { get; set; }

		public DysonSphereAddShellPacket()
		{
		}

		public DysonSphereAddShellPacket(int starIndex, int layerId, int shellId, int protoId, List<int> nodeIds)
		{
			StarIndex = starIndex;
			LayerId = layerId;
			ShellId = shellId;
			ProtoId = protoId;
			NodeIds = nodeIds.ToArray();
		}
	}
	public class DysonSphereColorChangePacket
	{
		public enum ComponentType : byte
		{
			Node,
			Frame,
			Shell
		}

		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public Float4 Color { get; set; }

		public ComponentType Type { get; set; }

		public int Index { get; set; }

		public DysonSphereColorChangePacket()
		{
		}

		public DysonSphereColorChangePacket(int starIndex, int layerId, Color32 color, ComponentType component, int index)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			StarIndex = starIndex;
			LayerId = layerId;
			Color = Float4.ToFloat4(color);
			Type = component;
			Index = index;
		}
	}
	public class DysonSphereEditLayerPacket
	{
		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public Float4 OrbitRotation { get; set; }

		public DysonSphereEditLayerPacket()
		{
		}

		public DysonSphereEditLayerPacket(int starIndex, int layerId, Quaternion orbitRotation)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			StarIndex = starIndex;
			LayerId = layerId;
			OrbitRotation = new Float4(orbitRotation);
		}
	}
	public class DysonSpherePaintCellsPacket
	{
		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public Float4 Paint { get; set; }

		public float Strength { get; set; }

		public bool SuperBrightMode { get; set; }

		public int[] CursorCells { get; set; }

		public int CellCount { get; set; }

		public DysonSpherePaintCellsPacket()
		{
		}

		public DysonSpherePaintCellsPacket(int starIndex, int layerId, Color32 paint, float strength, bool superBrightMode, int[] cursorCells, int cellCount)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			StarIndex = starIndex;
			LayerId = layerId;
			Paint = Float4.ToFloat4(paint);
			Strength = strength;
			SuperBrightMode = superBrightMode;
			CursorCells = cursorCells;
			CellCount = cellCount;
		}
	}
	public class DysonSphereRemoveFramePacket
	{
		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public int FrameId { get; set; }

		public DysonSphereRemoveFramePacket()
		{
		}

		public DysonSphereRemoveFramePacket(int starIndex, int layerId, int frameId)
		{
			StarIndex = starIndex;
			LayerId = layerId;
			FrameId = frameId;
		}
	}
	public class DysonSphereRemoveLayerPacket
	{
		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public DysonSphereRemoveLayerPacket()
		{
		}

		public DysonSphereRemoveLayerPacket(int starIndex, int layerId)
		{
			StarIndex = starIndex;
			LayerId = layerId;
		}
	}
	public class DysonSphereRemoveNodePacket
	{
		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public int NodeId { get; set; }

		public DysonSphereRemoveNodePacket()
		{
		}

		public DysonSphereRemoveNodePacket(int starIndex, int layerId, int nodeId)
		{
			StarIndex = starIndex;
			LayerId = layerId;
			NodeId = nodeId;
		}
	}
	public class DysonSphereRemoveShellPacket
	{
		public int StarIndex { get; set; }

		public int LayerId { get; set; }

		public int ShellId { get; set; }

		public DysonSphereRemoveShellPacket()
		{
		}

		public DysonSphereRemoveShellPacket(int starIndex, int layerId, int shellId)
		{
			StarIndex = starIndex;
			LayerId = layerId;
			ShellId = shellId;
		}
	}
	public class DysonSwarmAddOrbitPacket
	{
		public int StarIndex { get; set; }

		public int OrbitId { get; set; }

		public float Radius { get; set; }

		public Float4 Rotation { get; set; }

		public DysonSwarmAddOrbitPacket()
		{
		}

		public DysonSwarmAddOrbitPacket(int starIndex, int orbitId, float radius, Quaternion rotation)
		{
			//IL_001c: 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)
			StarIndex = starIndex;
			OrbitId = orbitId;
			Radius = radius;
			Rotation = new Float4(rotation);
		}
	}
	public class DysonSwarmEditOrbitPacket
	{
		public int StarIndex { get; set; }

		public int OrbitId { get; set; }

		public float Radius { get; set; }

		public Float4 Rotation { get; set; }

		public Float4 Color { get; set; }

		public DysonSwarmEditOrbitPacket()
		{
		}

		public DysonSwarmEditOrbitPacket(int starIndex, int orbitId, float radius, Quaternion rotation)
		{
			//IL_001c: 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)
			StarIndex = starIndex;
			OrbitId = orbitId;
			Radius = radius;
			Rotation = new Float4(rotation);
		}

		public DysonSwarmEditOrbitPacket(int starIndex, int orbitId, Vector4 color)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			StarIndex = starIndex;
			OrbitId = orbitId;
			Color = new Float4(color.x, color.y, color.z, color.w);
			Radius = -1f;
		}
	}
	public class DysonSwarmRemoveOrbitPacket
	{
		public int StarIndex { get; set; }

		public int OrbitId { get; set; }

		public SwarmRemoveOrbitEvent Event { get; set; }

		public DysonSwarmRemoveOrbitPacket()
		{
		}

		public DysonSwarmRemoveOrbitPacket(int starIndex, int orbitId, SwarmRemoveOrbitEvent removeEvent)
		{
			StarIndex = starIndex;
			OrbitId = orbitId;
			Event = removeEvent;
		}
	}
	public enum SwarmRemoveOrbitEvent
	{
		Remove,
		Disable,
		Enable,
		RemoveSails
	}
}
namespace NebulaModel.Packets.Trash
{
	public class TrashSystemClearAllTrashPacket
	{
	}
	public class TrashSystemLootFilterPacket
	{
		public byte[] EnemyDropBansData { get; set; }

		public TrashSystemLootFilterPacket()
		{
		}

		public TrashSystemLootFilterPacket(byte[] enemyDropBansData)
		{
			EnemyDropBansData = enemyDropBansData;
		}
	}
	public class TrashSystemNewPlanetTrashPacket
	{
		public int TrashId { get; set; }

		public int PlanetId { get; set; }

		public Float3 Pos { get; set; }

		public int Life { get; set; }

		public int ItemId { get; set; }

		public int Count { get; set; }

		public int Inc { get; set; }

		public TrashSystemNewPlanetTrashPacket()
		{
		}

		public TrashSystemNewPlanetTrashPacket(int trashId, in TrashObject trashObject, in TrashData trashData)
		{
			//IL_001b: 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)
			TrashId = trashId;
			PlanetId = trashData.nearPlanetId;
			Pos = DataStructureExtensions.ToFloat3(trashData.lPos);
			Life = trashData.life;
			ItemId = trashObject.item;
			Count = trashObject.count;
			Inc = trashObject.inc;
		}
	}
	public class TrashSystemNewPlayerTrashPacket
	{
		public ushort PlayerId { get; set; }

		public int TrashId { get; set; }

		public int NearStarId { get; set; }

		public int Life { get; set; }

		public Double3 UVel { get; set; }

		public int ItemId { get; set; }

		public int Count { get; set; }

		public int Inc { get; set; }

		public TrashSystemNewPlayerTrashPacket()
		{
		}

		public TrashSystemNewPlayerTrashPacket(ushort playerId, int trashId, in TrashObject trashObject, in TrashData trashData)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			PlayerId = playerId;
			TrashId = trashId;
			NearStarId = trashData.nearStarId;
			Life = trashData.life;
			UVel = new Double3(trashData.uVel.x, trashData.uVel.y, trashData.uVel.z);
			ItemId = trashObject.item;
			Count = trashObject.count;
			Inc = trashObject.inc;
		}
	}
	public class TrashSystemTrashRemovedPacket
	{
		public int TrashId { get; set; }

		public int ItemId { get; set; }

		public TrashSystemTrashRemovedPacket()
		{
		}

		public TrashSystemTrashRemovedPacket(int trashId, int itemId)
		{
			TrashId = trashId;
			ItemId = itemId;
		}
	}
}
namespace NebulaModel.Packets.Statistics
{
	public class MilestoneUnlockPacket
	{
		public int Id { get; set; }

		public long UnlockTick { get; set; }

		public int PatternId { get; set; }

		public long[] Parameters { get; set; }

		public MilestoneUnlockPacket()
		{
		}

		public MilestoneUnlockPacket(int id, long unlockTick, int patternId, long[] parameters)
		{
			Id = id;
			UnlockTick = unlockTick;
			PatternId = patternId;
			Parameters = parameters;
		}
	}
	public class StatisticsDataPacket
	{
		public byte[] StatisticsBinaryData { get; set; }

		public StatisticsDataPacket()
		{
		}

		public StatisticsDataPacket(byte[] statisticsBinaryData)
		{
			StatisticsBinaryData = statisticsBinaryData;
		}
	}
	public class StatisticsRequestEvent
	{
		public StatisticEvent Event { get; set; }

		public StatisticsRequestEvent()
		{
		}

		public StatisticsRequestEvent(StatisticEvent Event)
		{
			this.Event = Event;
		}
	}
	public enum StatisticEvent
	{
		WindowOpened = 1,
		WindowClosed
	}
	public class StatisticUpdateDataPacket
	{
		public byte[] StatisticsBinaryData { get; set; }

		public StatisticUpdateDataPacket()
		{
		}

		public StatisticUpdateDataPacket(byte[] statisticsBinaryData)
		{
			StatisticsBinaryData = statisticsBinaryData;
		}
	}
}
namespace NebulaModel.Packets.Session
{
	public class GlobalGameDataRequest
	{
	}
	public class GlobalGameDataResponse
	{
		public enum EDataType : byte
		{
			History = 1,
			SpaceSector,
			MilestoneSystem,
			TrashSystem,
			Ready
		}

		public EDataType DataType { get; set; }

		public byte[] BinaryData { get; set; }

		public GlobalGameDataResponse()
		{
		}

		public GlobalGameDataResponse(EDataType dataType, byte[] binaryData)
		{
			DataType = dataType;
			BinaryData = binaryData;
		}
	}
	public class HandshakeResponse
	{
		public int GalaxyAlgo { get; set; }

		public int GalaxySeed { get; set; }

		public int StarCount { get; set; }

		public float ResourceMultiplier { get; set; }

		public bool IsPeaceMode { get; set; }

		public bool IsSandboxMode { get; set; }

		public int[] SavedThemeIds { get; set; }

		public byte[] CombatSettingsData { get; set; }

		public bool IsNewPlayer { get; set; }

		public PlayerData LocalPlayerData { get; set; }

		public byte[] ModsSettings { get; set; }

		public int ModsSettingsCount { get; set; }

		public bool SyncSoil { get; set; }

		public ushort NumPlayers { get; set; }

		public string DiscordPartyId { get; set; }

		public HandshakeResponse()
		{
		}

		public HandshakeResponse(in GameDesc gameDesc, byte[] combatSettingsData, bool isNewPlayer, PlayerData localPlayerData, byte[] modsSettings, int settingsCount, bool syncSoil, ushort numPlayers, string discordPartyId)
		{
			GalaxyAlgo = gameDesc.galaxyAlgo;
			GalaxySeed = gameDesc.galaxySeed;
			StarCount = gameDesc.starCount;
			ResourceMultiplier = gameDesc.resourceMultiplier;
			IsPeaceMode = gameDesc.isPeaceMode;
			IsSandboxMode = gameDesc.isSandboxMode;
			SavedThemeIds = gameDesc.savedThemeIds;
			CombatSettingsData = combatSettingsData;
			IsNewPlayer = isNewPlayer;
			LocalPlayerData = localPlayerData;
			ModsSettings = modsSettings;
			ModsSettingsCount = settingsCount;
			SyncSoil = syncSoil;
			NumPlayers = numPlayers;
			DiscordPartyId = discordPartyId;
		}
	}
	public class LobbyRequest
	{
		public string Username { get; set; }

		public byte[] ModsVersion { get; set; }

		public int ModsCount { get; set; }

		public int GameVersionSig { get; set; }

		public byte[] ClientCert { get; set; }

		public LobbyRequest()
		{
		}

		public LobbyRequest(byte[] clientCert, string username)
		{
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			Username = username;
			using (BinaryUtils.Writer writer = new BinaryUtils.Writer())
			{
				int num = 0;
				foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
				{
					BaseUnityPlugin instance = pluginInfo.Value.Instance;
					IMultiplayerMod val = (IMultiplayerMod)(object)((instance is IMultiplayerMod) ? instance : null);
					if (val != null)
					{
						writer.BinaryWriter.Write(pluginInfo.Key);
						writer.BinaryWriter.Write(val.Version);
						num++;
						continue;
					}
					foreach (BepInDependency dependency in pluginInfo.Value.Dependencies)
					{
						if (!(dependency.DependencyGUID != "dsp.nebula-multiplayer-api"))
						{
							writer.BinaryWriter.Write(pluginInfo.Key);
							writer.BinaryWriter.Write(pluginInfo.Value.Metadata.Version.ToString());
							num++;
						}
					}
				}
				ModsVersion = writer.CloseAndGetBytes();
				ModsCount = num;
			}
			Version gameVersion = GameConfig.gameVersion;
			GameVersionSig = ((Version)(ref gameVersion)).sig;
			ClientCert = clientCert;
		}
	}
	public class LobbyResponse
	{
		public int GalaxyAlgo { get; set; }

		public int GalaxySeed { get; set; }

		public int StarCount { get; set; }

		public float ResourceMultiplier { get; set; }

		public bool IsPeaceMode { get; set; }

		public bool IsSandboxMode { get; set; }

		public int[] SavedThemeIds { get; set; }

		public byte[] CombatSettingsData { get; set; }

		public byte[] ModsSettings { get; set; }

		public int ModsSettingsCount { get; set; }

		public ushort NumPlayers { get; set; }

		public string DiscordPartyId { get; set; }

		public LobbyResponse()
		{
		}

		public LobbyResponse(in GameDesc gameDesc, byte[] combatSettingsData, byte[] modsSettings, int settingsCount, ushort numPlayers, string discordPartyId)
		{
			GalaxyAlgo = gameDesc.galaxyAlgo;
			GalaxySeed = gameDesc.galaxySeed;
			StarCount = gameDesc.starCount;
			ResourceMultiplier = gameDesc.resourceMultiplier;
			IsPeaceMode = gameDesc.isPeaceMode;
			IsSandboxMode = gameDesc.isSandboxMode;
			CombatSettingsData = combatSettingsData;
			SavedThemeIds = gameDesc.savedThemeIds;
			ModsSettings = modsSettings;
			ModsSettingsCount = settingsCount;
			NumPlayers = numPlayers;
			DiscordPartyId = discordPartyId;
		}
	}
	public class LobbyUpdateCombatValues
	{
		public float CombatAggressiveness { get; set; }

		public float CombatInitialLevel { get; set; }

		public float CombatInitialGrowth { get; set; }

		public float CombatInitialColonize { get; set; }

		public float CombatMaxDensity { get; set; }

		public float CombatGrowthSpeedFactor { get; set; }

		public float CombatPowerThreatFactor { get; set; }

		public float CombatBattleThreatFactor { get; set; }

		public float CombatBattleExpFactor { get; set; }

		public LobbyUpdateCombatValues()
		{
		}

		public LobbyUpdateCombatValues(CombatSettings combatSettings)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			CombatAggressiveness = combatSettings.aggressiveness;
			CombatInitialLevel = combatSettings.initialLevel;
			CombatInitialGrowth = combatSettings.initialGrowth;
			CombatInitialColonize = combatSettings.initialColonize;
			CombatMaxDensity = combatSettings.maxDensity;
			CombatGrowthSpeedFactor = combatSettings.growthSpeedFactor;
			CombatPowerThreatFactor = combatSettings.powerThreatFactor;
			CombatBattleThreatFactor = combatSettings.battleThreatFactor;
			CombatBattleExpFactor = combatSettings.battleExpFactor;
		}
	}
	public class LobbyUpdateValues
	{
		public int GalaxyAlgo { get; set; }

		public int GalaxySeed { get; set; }

		public int StarCount { get; set; }

		public float ResourceMultiplier { get; set; }

		public bool IsSandboxMode { get; set; }

		public bool IsPeaceMode { get; set; }

		public float CombatAggressiveness { get; set; }

		public float CombatInitialLevel { get; set; }

		public float CombatInitialGrowth { get; set; }

		public float CombatInitialColonize { get; set; }

		public float CombatMaxDensity { get; set; }

		public float CombatGrowthSpeedFactor { get; set; }

		public float CombatPowerThreatFactor { get; set; }

		public float CombatBattleThreatFactor { get; set; }

		public float CombatBattleExpFactor { get; set; }

		public LobbyUpdateValues()
		{
		}

		public LobbyUpdateValues(int galaxyAlgo, int galaxySeed, int starCount, float resourceMultiplier, bool isSandboxMode, bool isPeaceMode, CombatSettings combatSettings)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			GalaxyAlgo = galaxyAlgo;
			GalaxySeed = galaxySeed;
			StarCount = starCount;
			ResourceMultiplier = resourceMultiplier;
			IsSandboxMode = isSandboxMode;
			IsPeaceMode = isPeaceMode;
			CombatAggressiveness = combatSettings.aggressiveness;
			CombatInitialLevel = combatSettings.initialLevel;
			CombatInitialGrowth = combatSettings.initialGrowth;
			CombatInitialColonize = combatSettings.initialColonize;
			CombatMaxDensity = combatSettings.maxDensity;
			CombatGrowthSpeedFactor = combatSettings.growthSpeedFactor;
			CombatPowerThreatFactor = combatSettings.powerThreatFactor;
			CombatBattleThreatFactor = combatSettings.battleThreatFactor;
			CombatBattleExpFactor = combatSettings.battleExpFactor;
		}
	}
	public class PlayerDisconnected
	{
		public ushort PlayerId { get; set; }

		public ushort NumPlayers { get; set; }

		public PlayerDisconnected()
		{
		}

		public PlayerDisconnected(ushort playerId, ushort numPlayers)
		{
			PlayerId = playerId;
			NumPlayers = numPlayers;
		}
	}
	public class PlayerJoining
	{
		public PlayerData PlayerData { get; set; }

		public ushort NumPlayers { get; set; }

		public PlayerJoining()
		{
		}

		public PlayerJoining(PlayerData playerData, ushort numPlayers)
		{
			PlayerData = playerData;
			NumPlayers = numPlayers;
		}
	}
	public class StartGameMessage
	{
		public bool IsAllowedToStart { get; set; }

		public PlayerData LocalPlayerData { get; set; }

		public bool SyncSoil { get; set; }

		public StartGameMessage()
		{
		}

		public StartGameMessage(bool isAllowedToStart, PlayerData localPlayerData, bool syncSoil)
		{
			IsAllowedToStart = isAllowedToStart;
			LocalPlayerData = localPlayerData;
			SyncSoil = syncSoil;
		}
	}
	public class SyncComplete
	{
		public PlayerData[] AllPlayers { get; set; }

		public byte[] ClientCert { get; set; }

		public SyncComplete()
		{
			AllPlayers = Array.Empty<PlayerData>();
			ClientCert = Array.Empty<byte>();
		}

		public SyncComplete(IEnumerable<IPlayerData> otherPlayers)
		{
			AllPlayers = otherPlayers.Select((IPlayerData data) => (PlayerData)(object)data).ToArray();
			ClientCert = Array.Empty<byte>();
		}

		public SyncComplete(byte[] clientCert)
		{
			AllPlayers = Array.Empty<PlayerData>();
			ClientCert = clientCert;
		}
	}
}
namespace NebulaModel.Packets.Routers
{
	public class PlanetBroadcastPacket
	{
		public byte[] PacketObject { get; set; }

		public int PlanetId { get; set; }

		public PlanetBroadcastPacket()
		{
		}

		public PlanetBroadcastPacket(byte[] packetObject, int planetId)
		{
			PacketObject = packetObject;
			PlanetId = planetId;
		}
	}
	public class StarBroadcastPacket
	{
		public byte[] PacketObject { get; set; }

		public int StarId { get; set; }

		public StarBroadcastPacket()
		{
		}

		public StarBroadcastPacket(byte[] packetObject, int starId)
		{
			PacketObject = packetObject;
			StarId = starId;
		}
	}
}
namespace NebulaModel.Packets.Players
{
	public class PlayerEjectMechaDronePacket
	{
		public ushort PlayerId { get; set; }

		public int PlanetId { get; set; }

		public int TargetObjectId { get; set; }

		public int Next1ObjectId { get; set; }

		public int Next2ObjectId { get; set; }

		public int Next3ObjectId { get; set; }

		public int DronePriority { get; set; }

		public PlayerEjectMechaDronePacket()
		{
		}

		public PlayerEjectMechaDronePacket(ushort playerId, int planetId, int targetObjectId, int next1ObjectId, int next2ObjectId, int next3ObjectId, int dronePriority)
		{
			PlayerId = playerId;
			PlanetId = planetId;
			TargetObjectId = targetObjectId;
			Next1ObjectId = next1ObjectId;
			Next2ObjectId = next2ObjectId;
			Next3ObjectId = next3ObjectId;
			DronePriority = dronePriority;
		}
	}
	public class PlayerGiveItemPacket
	{
		public int ItemId { get; set; }

		public int ItemCount { get; set; }

		public int ItemInc { get; set; }

		public PlayerGiveItemPacket()
		{
		}

		public PlayerGiveItemPacket(int itemId, int itemCount, int itemInc)
		{
			ItemId = itemId;
			ItemCount = itemCount;
			ItemInc = itemInc;
		}
	}
	public class PlayerMechaArmor
	{
		public ushort PlayerId { get; set; }

		public byte[] AppearanceData { get; set; }

		public PlayerMechaArmor()
		{
		}

		public PlayerMechaArmor(ushort playerId, byte[] appearanceData)
		{
			PlayerId = playerId;
			AppearanceData = appearanceData;
		}
	}
	[HidePacketInDebugLogs]
	public class PlayerMechaData
	{
		public MechaData Data { get; set; }

		public PlayerMechaData()
		{
		}

		public PlayerMechaData(Player player)
		{
			Data = new MechaData(player);
		}
	}
	public class PlayerMechaDIYArmor
	{
		public byte[] DIYAppearanceData { get; set; }

		public int[] DIYItemId { get; set; }

		public int[] DIYItemValue { get; set; }

		public PlayerMechaDIYArmor()
		{
		}

		public PlayerMechaDIYArmor(byte[] diyArmorData, int[] diyItemId, int[] diyItemValue)
		{
			DIYAppearanceData = diyArmorData;
			DIYItemId = diyItemId;
			DIYItemValue = diyItemValue;
		}
	}
	public class PlayerMechaStat
	{
		public int ItemId { get; set; }

		public int ItemCount { get; set; }

		public PlayerMechaStat()
		{
		}

		public PlayerMechaStat(int itemId, int itemCount)
		{
			ItemId = itemId;
			ItemCount = itemCount;
		}
	}
	[HidePacketInDebugLogs]
	public class PlayerMovement
	{
		[Flags]
		public enum EFlags : byte
		{
			isGrounded = 1,
			inWater = 2,
			warping = 4,
			hasShield = 8,
			chargeShieldBurst = 0x10
		}

		public ushort PlayerId { get; set; }

		public int LocalPlanetId { get; set; }

		public Float3 LocalPlanetPosition { get; set; }

		public Double3 UPosition { get; set; }

		public Float3 Rotation { get; set; }

		public Float3 BodyRotation { get; set; }

		public EMovementState MovementState { get; set; }

		public float HorzSpeed { get; set; }

		public float VertSpeed { get; set; }

		public float Turning { get; set; }

		public float JumpWeight { get; set; }

		public float JumpNormalizedTime { get; set; }

		public byte IdleAnimIndex { get; set; }

		public byte MiningAnimIndex { get; set; }

		public float MiningWeight { get; set; }

		public EFlags Flags { get; set; }

		public PlayerMovement()
		{
		}

		public PlayerMovement(ushort playerId, int localPlanetId, Float3 localPlanetPosition, Double3 uPosition, Float3 rotation, Float3 bodyRotation, PlayerAnimator animator)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			PlayerId = playerId;
			LocalPlanetId = localPlanetId;
			LocalPlanetPosition = localPlanetPosition;
			UPosition = uPosition;
			Rotation = rotation;
			BodyRotation = bodyRotation;
			MovementState = animator.movementState;
			HorzSpeed = animator.controller.horzSpeed;
			VertSpeed = animator.controller.vertSpeed;
			Turning = animator.turning;
			JumpWeight = animator.jumpWeight;
			JumpNormalizedTime = animator.jumpNormalizedTime;
			IdleAnimIndex = (byte)animator.idleAnimIndex;
			MiningAnimIndex = (byte)animator.miningAnimIndex;
			MiningWeight = animator.miningWeight;
			Flags = (EFlags)0;
			if (animator.controller.actionWalk.isGrounded)
			{
				Flags |= EFlags.isGrounded;
			}
			if (animator.controller.actionDrift.inWater)
			{
				Flags |= EFlags.inWater;
			}
			if (animator.player.warping)
			{
				Flags |= EFlags.warping;
			}
			Mecha mecha = animator.controller.mecha;
			if (mecha.energyShieldEnergy > 0)
			{
				Flags |= EFlags.hasShield;
			}
			if (mecha.energyShieldBurstProgress > 0.0)
			{
				Flags |= EFlags.chargeShieldBurst;
			}
		}
	}
	public class PlayerSandCount
	{
		public long SandCount { get; set; }

		public bool IsDelta { get; set; }

		public PlayerSandCount()
		{
		}

		public PlayerSandCount(long sandCount, bool isDelta = false)
		{
			SandCount = sandCount;
			IsDelta = isDelta;
		}
	}
	public class PlayerUpdateLocalStarId
	{
		public ushort PlayerId { get; set; }

		public int StarId { get; set; }

		public PlayerUpdateLocalStarId()
		{
		}

		public PlayerUpdateLocalStarId(ushort playerId, int starId)
		{
			PlayerId = playerId;
			StarId = starId;
		}
	}
}
namespace NebulaModel.Packets.Planet
{
	public class FactoryData
	{
		public int PlanetId { get; set; }

		public byte[] BinaryData { get; set; }

		public byte[] TerrainModData { get; set; }

		public FactoryData()
		{
		}

		public FactoryData(int id, byte[] data, byte[] terrainModData)
		{
			PlanetId = id;
			BinaryData = data;
			TerrainModData = terrainModData;
		}
	}
	public class FactoryLoadRequest
	{
		public int PlanetID { get; set; }

		public FactoryLoadRequest()
		{
		}

		public FactoryLoadRequest(int planetID)
		{
			PlanetID = planetID;
		}
	}
	public class PlanetDataRequest
	{
		public int[] PlanetIDs { get; set; }

		public PlanetDataRequest()
		{
		}

		public PlanetDataRequest(int[] planetIDs)
		{
			PlanetIDs = planetIDs;
		}
	}
	public class PlanetDataResponse
	{
		public int PlanetDataID { get; set; }

		public byte[] PlanetDataByte { get; set; }

		public PlanetDataResponse()
		{
		}

		public PlanetDataResponse(int planetId, byte[] planetData)
		{
			PlanetDataID = planetId;
			PlanetDataByte = planetData;
		}
	}
	public class PlanetDetailRequest
	{
		public int PlanetID { get; set; }

		public PlanetDetailRequest()
		{
		}

		public PlanetDetailRequest(int planetID)
		{
			PlanetID = planetID;
		}
	}
	public class PlanetDetailResponse
	{
		public int PlanetDataID { get; set; }

		public byte[] VeinTypes { get; set; }

		public int[] VeinCounts { get; set; }

		public long[] VeinAmounts { get; set; }

		public float LandPercent { get; set; }

		public PlanetDetailResponse()
		{
		}

		public PlanetDetailResponse(int planetId, in VeinGroup[] veinGroups, float landPercent)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected I4, but got Unknown
			PlanetDataID = planetId;
			VeinTypes = new byte[veinGroups.Length];
			VeinCounts = new int[veinGroups.Length];
			VeinAmounts = new long[veinGroups.Length];
			for (int i = 1; i < veinGroups.Length; i++)
			{
				VeinTypes[i] = (byte)(int)veinGroups[i].type;
				VeinCounts[i] = veinGroups[i].count;
				VeinAmounts[i] = veinGroups[i].amount;
			}
			LandPercent = landPercent;
		}
	}
	public class VegeAddPacket
	{
		public int PlanetId { get; set; }

		public bool IsVein { get; set; }

		public byte[] Data { get; set; }

		public VegeAddPacket()
		{
		}

		public VegeAddPacket(int planetId, bool isVein, byte[] data)
		{
			PlanetId = planetId;
			IsVein = isVein;
			Data = data;
		}
	}
	public class VegeMinedPacket
	{
		public int PlanetId { get; set; }

		public int VegeId { get; set; }

		public int Amount { get; set; }

		public bool IsVein { get; set; }

		public VegeMinedPacket()
		{
		}

		public VegeMinedPacket(int planetId, int vegeId, int amount, bool isVein)
		{
			PlanetId = planetId;
			VegeId = vegeId;
			Amount = amount;
			IsVein = isVein;
		}
	}
}
namespace NebulaModel.Packets.Logistics
{
	public class DispenserAddTakePacket
	{
		public int PlanetId { get; set; }

		public int EntityId { get; set; }

		public EDispenserAddTakeEvent AddTakeEvent { get; set; }

		public int ItemId { get; set; }

		public int ItemCount { get; set; }

		public int ItemInc { get; set; }

		public DispenserAddTakePacket()
		{
		}

		public DispenserAddTakePacket(int planetId, int entityId, EDispenserAddTakeEvent addTakeEvent, int itemId, int itemCount, int itemInc)
		{
			PlanetId = planetId;
			EntityId = entityId;
			AddTakeEvent = addTakeEvent;
			ItemId = itemId;
			ItemCount = itemCount;
			ItemInc = itemInc;
		}
	}
	public enum EDispenserAddTakeEvent
	{
		None,
		ManualAdd,
		ManualTake,
		CourierAdd,
		CourierTake
	}
	public class DispenserCourierPacket
	{
		public int PlanetId { get; set; }

		public int PlayerId { get; set; }

		public int DispenserId { get; set; }

		public int ItemId { get; set; }

		public int ItemCount { get; set; }

		public DispenserCourierPacket()
		{
		}

		public DispenserCourierPacket(int planetId, int playerId, int dispenserId, int itemId, int itemCount)
		{
			PlanetId = planetId;
			PlayerId = playerId;
			DispenserId = dispenserId;
			ItemId = itemId;
			ItemCount = itemCount;
		}
	}
	public class DispenserSettingPacket
	{
		public int PlanetId { get; set; }

		public int DispenserId { get; set; }

		public EDispenserSettingEvent Event { get; set; }

		public int Parameter1 { get; set; }

		public DispenserSettingPacket()
		{
		}

		public DispenserSettingPacket(int planetId, int dispenserId, EDispenserSettingEvent settingEvent, int parameter1)
		{
			PlanetId = planetId;
			DispenserId = dispenserId;
			Event = settingEvent;
			Parameter1 = parameter1;
		}
	}
	public enum EDispenserSettingEvent
	{
		None,
		SetCourierCount,
		ToggleAutoReplenish,
		SetMaxChargePower,
		SetFilter,
		SetPlayerDeliveryMode,
		SetStorageDeliveryMode
	}
	public class DispenserStorePacket
	{
		public int PlanetId { get; set; }

		public int DispenserId { get; set; }

		public int HoldupItemCount { get; set; }

		public int[] ItemIds { get; set; }

		public int[] Counts { get; set; }

		public int[] Incs { get; set; }

		public DispenserStorePacket()
		{
		}

		public DispenserStorePacket(int planetId, in DispenserComponent dispenser)
		{
			PlanetId = planetId;
			DispenserId = dispenser.id;
			HoldupItemCount = dispenser.holdupItemCount;
			ItemIds = new int[HoldupItemCount];
			Counts = new int[HoldupItemCount];
			Incs = new int[HoldupItemCount];
			for (int i = 0; i < HoldupItemCount; i++)
			{
				ItemIds[i] = dispenser.holdupPackage[i].itemId;
				Counts[i] = dispenser.holdupPackage[i].count;
				Incs[i] = dispenser.holdupPackage[i].inc;
			}
		}
	}
	public class ILSAddStationComponent
	{
		public int PlanetId { get; set; }

		public int StationId { get; set; }

		public int StationGId { get; set; }

		public int EntityId { get; set; }

		public int MaxShipCount { get; set; }

		public ILSAddStationComponent()
		{
		}

		public ILSAddStationComponent(int planetId, int stationId, int stationGId, int entityId, int maxShipCount)
		{
			StationGId = stationGId;
			PlanetId = planetId;
			StationId = stationId;
			EntityId = entityId;
			MaxShipCount = maxShipCount;
		}
	}
	public class ILSArriveStarPlanetRequest
	{
		public int StarId { get; set; }

		public ILSArriveStarPlanetRequest()
		{
		}

		public ILSArriveStarPlanetRequest(int starId)
		{
			StarId = starId;
		}
	}
	public class ILSArriveStarPlanetResponse
	{
		public int[] StationGId { get; set; }

		public int[] StationPId { get; set; }

		public int[] StationMaxShips { get; set; }

		public int[] StorageLength { get; set; }

		public int[] SlotLength { get; set; }

		public int[] StorageIdx { get; set; }

		public int[] ItemId { get; set; }

		public int[] Count { get; set; }

		public int[] Inc { get; set; }

		public ILSArriveStarPlanetResponse()
		{
		}

		public ILSArriveStarPlanetResponse(int[] stationGId, int[] planetId, int[] stationMaxShips, int[] storageLength, int[] storageIdx, int[] slotLength, int[] itemId, int[] count, int[] inc)
		{
			StationGId = stationGId;
			StationPId = planetId;
			StationMaxShips = stationMaxShips;
			StorageLength = storageLength;
			StorageIdx = storageIdx;
			SlotLength = slotLength;
			ItemId = itemId;
			Count = count;
			Inc = inc;
		}
	}
	public class ILSgStationPoolSync
	{
		public int[] stationGId { get; set; }

		public int[] stationMaxShipCount { get; set; }

		public int[] stationId { get; set; }

		public string[] stationName { get; set; }

		public Float3[] DockPos { get; set; }

		public Float4[] DockRot { get; set; }

		public int[] planetId { get; set; }

		public int[] workShipCount { get; set; }

		public int[] idleShipCount { get; set; }

		public ulong[] workShipIndices { get; set; }

		public ulong[] idleShipIndices { get; set; }

		public int[] shipStage { get; set; }

		public int[] shipDirection { get; set; }

		public float[] shipWarpState { get; set; }

		public int[] shipWarperCnt { get; set; }

		public int[] shipItemID { get; set; }

		public int[] shipItemCount { get; set; }

		public int[] shipPlanetA { get; set; }

		public int[] shipPlanetB { get; set; }

		public int[] shipOtherGId { get; set; }

		public float[] shipT { get; set; }

		public int[] shipIndex { get; set; }

		public Double3[] shipPos { get; set; }

		public Float4[] shipRot { get; set; }

		public Float3[] shipVel { get; set; }

		public float[] shipSpeed { get; set; }

		public Float3[] shipAngularVel { get; set; }

		public Double3[] shipPPosTemp { get; set; }

		public Float4[] shipPRotTemp { get; set; }

		public ILSgStationPoolSync()
		{
		}

		public ILSgStationPoolSync(int[] stationGId, int[] stationMaxShipCount, int[] stationId, string[] stationName, Float3[] DockPos, Float4[] DockRot, int[] planetId, int[] workShipCount, int[] idleShipCount, ulong[] workShipIndices, ulong[] idleShipIndices, int[] shipStage, int[] shipDirection, float[] shipWarpState, int[] shipWarperCnt, int[] shipItemID, int[] shipItemCount, int[] shipPlanetA, int[] shipPlanetB, int[] shipOtherGId, float[] shipT, int[] shipIndex, Double3[] shipPos, Float4[] shipRot, Float3[] shipVel, float[] shipSpeed, Float3[] shipAngularVel, Double3[] shipPPosTemp, Float4[] shipPRotTemp)
		{
			this.stationGId = stationGId;
			this.stationMaxShipCount = stationMaxShipCount;
			this.stationId = stationId;
			this.stationName = stationName;
			this.DockPos = DockPos;
			this.DockRot = DockRot;
			this.planetId = planetId;
			this.workShipCount = workShipCount;
			this.idleShipCount = idleShipCount;
			this.workShipIndices = workShipIndices;
			this.idleShipIndices = idleShipIndices;
			this.shipStage = shipStage;
			this.shipDirection = shipDirection;
			this.shipWarpState = shipWarpState;
			this.shipWarperCnt = shipWarperCnt;
			this.shipItemID = shipItemID;
			this.shipItemCount = shipItemCount;
			this.shipPlanetA = shipPlanetA;
			this.shipPlanetB = shipPlanetB;
			this.shipOtherGId = shipOtherGId;
			this.shipT = shipT;
			this.shipIndex = shipIndex;
			this.shipPos = shipPos;
			this.shipRot = shipRot;
			this.shipVel = shipVel;
			this.shipSpeed = shipSpeed;
			this.shipAngularVel = shipAngularVel;
			this.shipPPosTemp = shipPPosTemp;
			this.shipPRotTemp = shipPRotTemp;
		}
	}
	public class ILSIdleShipBackToWork
	{
		public int ThisGId { get; set; }

		public int PlanetA { get; set; }

		public int PlanetB { get; set; }

		public int OtherGId { get; set; }

		public int ItemId { get; set; }

		public int ItemCount { get; set; }

		public int Inc { get; set; }

		public int Gene { get; set; }

		public int ShipIndex { get; set; }

		public int ShipWarperCount { get; set; }

		public int StationMaxShipCount { get; set; }

		public int StationWarperCount { get; set; }

		public ILSIdleShipBackToWork()
		{
		}

		public ILSIdleShipBackToWork(ShipData ShipData, int thisGId, int stationMaxShipCount, int stationWarperCount)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			ThisGId = thisGId;
			PlanetA = ShipData.planetA;
			PlanetB = ShipData.planetB;
			OtherGId = ShipData.otherGId;
			ItemId = ShipData.itemId;
			ItemCount = ShipData.itemCount;
			Inc = ShipData.inc;
			Gene = ShipData.gene;
			ShipIndex = ShipData.shipIndex;
			ShipWarperCount = ShipData.warperCnt;
			StationMaxShipCount = stationMaxShipCount;
			StationWarperCount = stationWarperCount;
		}
	}
	public class ILSRematchRemotePairs
	{
		public int GId { get; set; }

		public int[] ShipIndex { get; set; }

		public int[] OtherGId { get; set; }

		public int[] Direction { get; set; }

		public int[] ItemId { get; set; }

		public ILSRematchRemotePairs()
		{
		}

		public ILSRematchRemotePairs(int gid, List<int> shipIndex, List<int> otherGId, List<int> direction, List<int> itemId)
		{
			GId = gid;
			ShipIndex = shipIndex.ToArray();
			OtherGId = otherGId.ToArray();
			Direction = direction.ToArray();
			ItemId = itemId.ToArray();
		}
	}
	public class ILSRemoveStationComponent
	{
		public int StationId { get; set; }

		public int PlanetId { get; set; }

		public int StationGId { get; set; }

		public ILSRemoveStationComponent()
		{
		}

		public ILSRemoveStationComponent(int stationId, int planetId, int stationGId)
		{
			StationId = stationId;
			PlanetId = planetId;
			StationGId = stationGId;
		}
	}
	public class ILSRequestgStationPoolSync
	{
	}
	public class ILSRequestShipDock
	{
		public int StationGId { get; set; }

		public ILSRequestShipDock()
		{
		}

		public ILSRequestShipDock(int stationGId)
		{
			StationGId = stationGId;
		}
	}
	public class ILSShipAddTake
	{
		public bool AddItem { get; set; }

		public int ItemId { get; set; }

		public int ItemCount { get; set; }

		public int StationGID { get; set; }

		public int Inc { get; set; }

		public ILSShipAddTake()
		{
		}

		public ILSShipAddTake(bool addItem, int itemId, int itemCount, int stationGID, int inc)
		{
			AddItem = addItem;
			ItemId = itemId;
			ItemCount = itemCount;
			StationGID = stationGID;
			Inc = inc;
		}
	}
	public class ILSShipDock
	{
		public int stationGId { get; set; }

		public Float3 shipDockPos { get; set; }

		public Float4 shipDockRot { get; set; }

		public int[] shipOtherGId { get; set; }

		public int[] shipIndex { get; set; }

		public Double3[] shipPos { get; set; }

		public Float4[] shipRot { get; set; }

		public Double3[] shipPPosTemp { get; set; }

		public Float4[] shipPRotTemp { get; set; }

		public ILSShipDock()
		{
		}

		public ILSShipDock(int stationGId, Vector3 shipDockPos, Quaternion shipDockRot, int[] shipOtherGId, int[] shipIndex, Double3[] shipPos, Float4[] shipRot, Double3[] shipPPosTemp, Float4[] shipPRotTemp)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			this.stationGId = stationGId;
			this.shipDockPos = new Float3(shipDockPos);
			this.shipDockRot = new Float4(shipDockRot);
			this.shipOtherGId = shipOtherGId;
			this.shipIndex = shipIndex;
			this.shipPos = shipPos;
			this.shipRot = shipRot;
			this.shipPPosTemp = shipPPosTemp;
			this.shipPRotTemp = shipPRotTemp;
		}
	}
	public class ILSShipEnterWarp
	{
		public int ThisGId { get; set; }

		public int WorkShipIndex { get; set; }

		public ILSShipEnterWarp()
		{
		}

		public ILSShipEnterWarp(int thisGId, int workShipIndex)
		{
			ThisGId = thisGId;
			WorkShipIndex = workShipIndex;
		}
	}
	public class ILSUpdateSlotData
	{
		public int PlanetId { get; set; }

		public int StationId { get; set; }

		public int StationGId { get; set; }

		public int Index { get; set; }

		public int StorageIdx { get; set; }

		public ILSUpdateSlotData()
		{
		}

		public ILSUpdateSlotData(int planetId, int stationId, int stationGId, int index, int storageIdx)
		{
			PlanetId = planetId;
			StationId = stationId;
			StationGId = stationGId;
			Index = index;
			StorageIdx = storageIdx;
		}
	}
	public class ILSUpdateStorage
	{
		public int GId { get; set; }

		public int Index { get; set; }

		public int Count { get; set; }

		public int Inc { get; set; }

		public ILSUpdateStorage()
		{
		}

		public ILSUpdateStorage(int gid, int index, int count, int inc)
		{
			GId = gid;
			Index = index;
			Count = count;
			Inc = inc;
		}
	}
	public class ILSWorkShipBackToIdle
	{
		public int GId { get; set; }

		public int PlanetA { get; set; }

		public int StationMaxShipCount { get; set; }

		public int ShipIndex { get; set; }

		public int WorkShipIndex { get; set; }

		public ILSWorkShipBackToIdle()
		{
		}

		public ILSWorkShipBackToIdle(StationComponent stationComponent, ShipData shipData, int workShipIndex)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			GId = stationComponent.gid;
			PlanetA = shipData.planetA;
			StationMaxShipCount = stationComponent.workShipDatas.Length;
			ShipIndex = shipData.shipIndex;
			WorkShipIndex = workShipIndex;
		}
	}
	public class RemoteOrderUpdate
	{
		public int StationGId { get; set; }

		public int[] RemoteOrder { get; set; }

		public RemoteOrderUpdate()
		{
		}

		public RemoteOrderUpdate(int stationGid, int[] remoteOrder)
		{
			StationGId = stationGid;
			RemoteOrder = remoteOrder;
		}
	}
	public class StationUI
	{
		public enum EUISettings
		{
			None,
			MaxChargePower,
			MaxTripDrones,
			MaxTripVessel,
			MinDeliverDrone,
			MinDeliverVessel,
			WarpDistance,
			WarperNeeded,
			IncludeCollectors,
			SetDroneCount,
			SetShipCount,
			SetWarperCount,
			PilerCount,
			MaxMiningSpeed,
			DroneAutoReplenish,
			ShipAutoReplenish
		}

		public int PlanetId { get; set; }

		public int StationId { get; set; }

		public int StationGId { get; set; }

		public EUISettings SettingIndex { get; set; }

		public float SettingValue { get; set; }

		public string SettingString { get; set; }

		public bool WarperShouldTakeFromStorage { get; set; }

		public bool ShouldRefund { get; set; }

		public StationUI()
		{
		}

		public StationUI(int planetId, int stationId, int stationGId, EUISettings settingIndex, float value, bool warperShouldTakeFromStorage = false)
		{
			PlanetId = planetId;
			StationId = stationId;
			StationGId = stationGId;
			SettingIndex = settingIndex;
			SettingValue = value;
			WarperShouldTakeFromStorage = warperShouldTakeFromStorage;
		}

		public StationUI(int planetId, int stationId, int stationGId, EUISettings settingIndex, string settingString)
		{
			PlanetId = planetId;
			StationId = stationId;
			StationGId = stationGId;
			SettingIndex = settingIndex;
			SettingString = settingString;
		}
	}
	public class StationUIInitialSync
	{
		public int PlanetId { get; set; }

		public int StationGId { get; set; }

		public int StationId { get; set; }

		public double TripRangeDrones { get; set; }

		public double TripRangeShips { get; set; }

		public int DeliveryDrones { get; set; }

		public int DeliveryShips { get; set; }

		public double WarperEnableDistance { get; set; }

		public bool WarperNecessary { get; set; }

		public bool IncludeOrbitCollector { get; set; }

		public long Energy { get; set; }

		public long EnergyPerTick { get; set; }

		public int PilerCount { get; set; }

		public int[] ItemId { get; set; }

		public int[] ItemCountMax { get; set; }

		public int[] ItemCount { get; set; }

		public int[] ItemInc { get; set; }

		public int[] LocalLogic { get; set; }

		public int[] RemoteLogic { get; set; }

		public int[] RemoteOrder { get; set; }

		public StationUIInitialSync()
		{
		}

		public StationUIInitialSync(int planetId, int stationId, int stationGId, double tripRangeDrones, double tripRangeShips, int deliveryDrones, int deliveryShips, double warperEnableDistance, bool warperNecessary, bool includeOrbitCollector, long energy, long energyPerTick, int pilerCount, int[] itemId, int[] itemCountMax, int[] itemCount, int[] itemInc, int[] localLogic, int[] remoteLogic, int[] remoteOrder)
		{
			PlanetId = planetId;
			StationId = stationId;
			StationGId = stationGId;
			TripRangeDrones = tripRangeDrones;
			TripRangeShips = tripRangeShips;
			DeliveryDrones = deliveryDrones;
			DeliveryShips = deliveryShips;
			WarperEnableDistance = warperEnableDistance;
			WarperNecessary = warperNecessary;
			IncludeOrbitCollector = includeOrbitCollector;
			Energy = energy;
			EnergyPerTick = energyPerTick;
			PilerCount = pilerCount;
			ItemId = itemId;
			ItemCountMax = itemCountMax;
			ItemCount = itemCount;
			ItemInc = itemInc;
			LocalLogic = localLogic;
			RemoteLogic = remoteLogic;
			RemoteOrder = remoteOrder;
		}
	}
	public class StationUIInitialSyncRequest
	{
		public int PlanetId { get; set; }

		public int StationId { get; set; }

		public int StationGId { get; set; }

		public StationUIInitialSyncRequest()
		{
		}

		public StationUIInitialSyncRequest(int planetId, int stationId, int stationGId)
		{
			PlanetId = planetId;
			StationId = stationId;
			StationGId = stationGId;
		}
	}
	public class StorageUI
	{
		public int PlanetId { get; set; }

		public int StationId { get; set; }

		public int StationGId { get; set; }

		public int StorageIdx { get; set; }

		public int ItemId { get; set; }

		public int ItemCountMax { get; set; }

		public ELogisticStorage LocalLogic { get; set; }

		public ELogisticStorage RemoteLogic { get; set; }

		public int ItemCount { get; set; }

		public int ItemInc { get; set; }

		public bool ShouldRefund { get; set; }

		public byte KeepMode { get; set; }

		public StorageUI()
		{
		}

		public StorageUI(int planetId, int stationId, int stationGId, int storageIdx, int itemId, int itemCountMax, ELogisticStorage localLogic, ELogisticStorage remoteLogic)
		{
			//IL_003b: 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)
			ItemCount = -1;
			PlanetId = planetId;
			StationId = stationId;
			StationGId = stationGId;
			StorageIdx = storageIdx;
			ItemId = itemId;
			ItemCountMax = itemCountMax;
			LocalLogic = localLogic;
			RemoteLogic = remoteLogic;
		}

		public StorageUI(int planetId, int stationId, int stationGId, int storageIdx, int itemCount, int itemInc)
		{
			ShouldRefund = false;
			PlanetId = planetId;
			StationId = stationId;
			StationGId = stationGId;
			StorageIdx = storageIdx;
			ItemCount = itemCount;
			ItemInc = itemInc;
		}

		public StorageUI(int planetId, int stationId, int stationGId, int storageIdx, byte keepMode)
		{
			ItemCount = -2;
			PlanetId = planetId;
			StationId = stationId;
			StationGId = stationGId;
			StorageIdx = storageIdx;
			KeepMode = keepMode;
		}
	}
}
namespace NebulaModel.Packets.GameStates
{
	public class FragmentInfo
	{
		public int Size { get; set; }

		public FragmentInfo()
		{
		}

		public FragmentInfo(int size)
		{
			Size = size;
		}
	}
	[HidePacketInDebugLogs]
	public class GameStateRequest
	{
		public long SentTimestamp { get; set; } = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

	}
	[HidePacketInDebugLogs]
	public class GameStateUpdate
	{
		public long SentTime { get; set; }

		public long GameTick { get; set; }

		public float UnitsPerSecond { get; set; }

		public GameStateUpdate()
		{
		}

		public GameStateUpdate(long sentTime, long gameTick, float unitsPerSecond)
		{
			SentTime = sentTime;
			GameTick = gameTick;
			UnitsPerSecond = unitsPerSecond;
		}
	}
}
namespace NebulaModel.Packets.GameHistory
{
	public class GameHistoryEnqueueTechPacket
	{
		public int TechId { get; set; }

		public GameHistoryEnqueueTechPacket()
		{
		}

		public GameHistoryEnqueueTechPacket(int techId)
		{
			TechId = techId;
		}
	}
	public class GameHistoryFeatureKeyPacket
	{
		public int FeatureId { get; set; }

		public bool Add { get; set; }

		public GameHistoryFeatureKeyPacket()
		{
		}

		public GameHistoryFeatureKeyPacket(int featureId, bool add)
		{
			FeatureId = featureId;
			Add = add;
		}
	}
	public class GameHistoryNotificationPacket
	{
		public GameHistoryEvent Event { get; set; }

		public GameHistoryNotificationPacket()
		{
		}

		public GameHistoryNotificationPacket(GameHistoryEvent Event)
		{
			this.Event = Event;
		}
	}
	public enum GameHistoryEvent
	{
		PauseQueue = 1,
		ResumeQueue,
		OneKeyUnlock
	}
	public class GameHistoryRemoveTechPacket
	{
		public int TechId { get; set; }

		public GameHistoryRemoveTechPacket()
		{
		}

		public GameHistoryRemoveTechPacket(int techId)
		{
			TechId = techId;
		}
	}
	public class GameHistoryResearchContributionPacket
	{
		public long Hashes { get; set; }

		public int TechId { get; set; }

		public GameHistoryResearchContributionPacket()
		{
		}

		public GameHistoryResearchContributionPacket(long hashes, int techId)
		{
			Hashes = hashes;
			TechId = techId;
		}
	}
	public class GameHistoryResearchUpdatePacket
	{
		public int TechId { get; set; }

		public long HashUploaded { get; set; }

		public long HashNeeded { get; set; }

		public int TechHashedFor10Frames { get; set; }

		public ushort TechQueueLength { get; set; }

		public GameHistoryResearchUpdatePacket()
		{
		}

		public GameHistoryResearchUpdatePacket(int techId, long hashUploaded, long hashNeeded, int techHashedFor10Frames, int techQueueLength)
		{
			TechId = techId;
			HashUploaded = hashUploaded;
			HashNeeded = hashNeeded;
			TechHashedFor10Frames = techHashedFor10Frames;
			TechQueueLength = (ushort)techQueueLength;
		}
	}
	public class GameHistoryTechQueueSyncRequest
	{
		public int[] TechQueue { get; set; }

		public GameHistoryTechQueueSyncRequest()
		{
		}

		public GameHistoryTechQueueSyncRequest(int[] techQueue)
		{
			TechQueue = techQueue;
		}
	}
	public class GameHistoryUnlockTechPacket
	{
		public int TechId { get; set; }

		public int Level { get; set; }

		public GameHistoryUnlockTechPacket()
		{
		}

		public GameHistoryUnlockTechPacket(int techId, int level)
		{
			TechId = techId;
			Level = level;
		}
	}
}
namespace NebulaModel.Packets.Factory
{
	public class BuildEntityRequest
	{
		public int PlanetId { get; set; }

		public int PrebuildId { get; set; }

		public int AuthorId { get; set; }

		public int EntityId { get; set; }

		public BuildEntityRequest()
		{
		}

		public BuildEntityRequest(int planetId, int prebuildId, int authorId, int entityId)
		{
			PlanetId = planetId;
			PrebuildId = prebuildId;
			AuthorId = authorId;
			EntityId = entityId;
		}
	}
	public class CreatePrebuildsRequest
	{
		public int PlanetId { get; set; }

		public byte[] BuildPreviewData { get; set; }

		public int AuthorId { get; set; }

		public string BuildToolType { get; set; }

		public int PrebuildId { get; set; }

		public CreatePrebuildsRequest()
		{
		}

		public CreatePrebuildsRequest(int planetId, List<BuildPreview> buildPreviews, int playerId, str

NebulaNetwork.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NebulaAPI;
using NebulaAPI.DataStructures;
using NebulaAPI.GameState;
using NebulaAPI.Interfaces;
using NebulaAPI.Networking;
using NebulaAPI.Packets;
using NebulaModel;
using NebulaModel.DataStructures;
using NebulaModel.DataStructures.Chat;
using NebulaModel.Logger;
using NebulaModel.Networking;
using NebulaModel.Networking.Serialization;
using NebulaModel.Packets;
using NebulaModel.Packets.Chat;
using NebulaModel.Packets.Combat;
using NebulaModel.Packets.Combat.DFHive;
using NebulaModel.Packets.Combat.DFRelay;
using NebulaModel.Packets.Combat.DFTinder;
using NebulaModel.Packets.Combat.GroundEnemy;
using NebulaModel.Packets.Combat.Mecha;
using NebulaModel.Packets.Combat.SpaceEnemy;
using NebulaModel.Packets.Factory;
using NebulaModel.Packets.Factory.Assembler;
using NebulaModel.Packets.Factory.BattleBase;
using NebulaModel.Packets.Factory.Belt;
using NebulaModel.Packets.Factory.Ejector;
using NebulaModel.Packets.Factory.Foundation;
using NebulaModel.Packets.Factory.Fractionator;
using NebulaModel.Packets.Factory.Inserter;
using NebulaModel.Packets.Factory.Laboratory;
using NebulaModel.Packets.Factory.Miner;
using NebulaModel.Packets.Factory.Monitor;
using NebulaModel.Packets.Factory.PowerExchanger;
using NebulaModel.Packets.Factory.PowerGenerator;
using NebulaModel.Packets.Factory.PowerTower;
using NebulaModel.Packets.Factory.RayReceiver;
using NebulaModel.Packets.Factory.Silo;
using NebulaModel.Packets.Factory.Splitter;
using NebulaModel.Packets.Factory.Storage;
using NebulaModel.Packets.Factory.Tank;
using NebulaModel.Packets.Factory.Turret;
using NebulaModel.Packets.GameHistory;
using NebulaModel.Packets.GameStates;
using NebulaModel.Packets.Logistics;
using NebulaModel.Packets.Planet;
using NebulaModel.Packets.Players;
using NebulaModel.Packets.Routers;
using NebulaModel.Packets.Session;
using NebulaModel.Packets.Statistics;
using NebulaModel.Packets.Trash;
using NebulaModel.Packets.Universe;
using NebulaModel.Packets.Universe.Editor;
using NebulaModel.Packets.Warning;
using NebulaModel.Utils;
using NebulaNetwork.Messaging;
using NebulaNetwork.Ngrok;
using NebulaWorld;
using NebulaWorld.Chat.Commands;
using NebulaWorld.Combat;
using NebulaWorld.Factory;
using NebulaWorld.GameStates;
using NebulaWorld.Logistics;
using NebulaWorld.MonoBehaviours.Local.Chat;
using NebulaWorld.SocialIntegration;
using NebulaWorld.Trash;
using NebulaWorld.Universe;
using NebulaWorld.Warning;
using Open.Nat;
using UnityEngine;
using UnityEngine.UI;
using WebSocketSharp;
using WebSocketSharp.Net;
using WebSocketSharp.Server;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("0.9.3.3")]
[assembly: AssemblyInformationalVersion("0.9.3.3+3bb1ae4")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("NebulaNetwork")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyProduct("NebulaNetwork")]
[assembly: AssemblyTitle("NebulaNetwork")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.9.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[GeneratedCode("Nerdbank.GitVersioning.Tasks", "3.6.133.12845")]
[ExcludeFromCodeCoverage]
internal static class ThisAssembly
{
	internal const string AssemblyConfiguration = "Release";

	internal const string AssemblyFileVersion = "0.9.3.3";

	internal const string AssemblyInformationalVersion = "0.9.3.3+3bb1ae4";

	internal const string AssemblyName = "NebulaNetwork";

	internal const string AssemblyTitle = "NebulaNetwork";

	internal const string AssemblyVersion = "0.9.3.0";

	internal static readonly DateTime GitCommitDate = new DateTime(638486122650000000L, DateTimeKind.Utc);

	internal const string GitCommitId = "3bb1ae4284b5f16508d9789eff7fcce645bb08ea";

	internal const bool IsPrerelease = false;

	internal const bool IsPublicRelease = true;

	internal const string RootNamespace = "NebulaNetwork";
}
namespace NebulaModel.Packets
{
	public abstract class PacketProcessor<T> : BasePacketProcessor<T>
	{
		protected ConcurrentPlayerCollection Players => Multiplayer.Session.Server.Players;

		protected IServer Server => Multiplayer.Session.Server;

		protected IClient Client => Multiplayer.Session.Client;

		public override void ProcessPacket(T packet, INebulaConnection conn)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			ProcessPacket(packet, (NebulaConnection)conn);
		}

		protected abstract void ProcessPacket(T packet, NebulaConnection conn);
	}
}
namespace NebulaNetwork
{
	public class Client : IClient, INetworkProvider, IDisposable
	{
		private const float FRAGEMENT_UPDATE_INTERVAL = 0.1f;

		private const float GAME_STATE_UPDATE_INTERVAL = 1f;

		private const float MECHA_SYNCHONIZATION_INTERVAL = 30f;

		private readonly FieldRef<WebSocket, MemoryStream> fragmentsBufferRef = AccessTools.FieldRefAccess<WebSocket, MemoryStream>("_fragmentsBuffer");

		private readonly string serverPassword;

		private WebSocket clientSocket;

		private float fragmentUpdateTimer;

		private float gameStateUpdateTimer;

		private float mechaSynchonizationTimer;

		private NebulaConnection serverConnection;

		private bool websocketAuthenticationFailure;

		public INetPacketProcessor PacketProcessor { get; set; } = (INetPacketProcessor)new NebulaNetPacketProcessor();


		public IPEndPoint ServerEndpoint { get; set; }

		public Client(string url, int port, string password = "")
			: this(new IPEndPoint(Dns.GetHostEntry(url).AddressList[0], port), password)
		{
		}

		public Client(IPEndPoint endpoint, string password = "")
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			ServerEndpoint = endpoint;
			serverPassword = password;
		}

		public void Start()
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			foreach (Assembly nebulaAssembly in AssembliesUtils.GetNebulaAssemblies())
			{
				INetPacketProcessor packetProcessor = PacketProcessor;
				PacketUtils.RegisterAllPacketNestedTypesInAssembly(nebulaAssembly, (NetPacketProcessor)(object)((packetProcessor is NebulaNetPacketProcessor) ? packetProcessor : null));
			}
			INetPacketProcessor packetProcessor2 = PacketProcessor;
			PacketUtils.RegisterAllPacketProcessorsInCallingAssembly((NetPacketProcessor)(object)((packetProcessor2 is NebulaNetPacketProcessor) ? packetProcessor2 : null), false);
			foreach (Assembly targetAssembly in NebulaModAPI.TargetAssemblies)
			{
				INetPacketProcessor packetProcessor3 = PacketProcessor;
				PacketUtils.RegisterAllPacketNestedTypesInAssembly(targetAssembly, (NetPacketProcessor)(object)((packetProcessor3 is NebulaNetPacketProcessor) ? packetProcessor3 : null));
				INetPacketProcessor packetProcessor4 = PacketProcessor;
				PacketUtils.RegisterAllPacketProcessorsInAssembly(targetAssembly, (NetPacketProcessor)(object)((packetProcessor4 is NebulaNetPacketProcessor) ? packetProcessor4 : null), false);
			}
			clientSocket = new WebSocket($"ws://{ServerEndpoint}/socket", Array.Empty<string>());
			clientSocket.Log.Level = (LogLevel)1;
			clientSocket.Log.Output = Log.SocketOutput;
			clientSocket.OnOpen += ClientSocket_OnOpen;
			clientSocket.OnClose += ClientSocket_OnClose;
			clientSocket.OnMessage += ClientSocket_OnMessage;
			Action<LogData, string> currentLogOutput = clientSocket.Log.Output;
			clientSocket.Log.Output = delegate(LogData logData, string arg2)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Invalid comparison between Unknown and I4
				currentLogOutput(logData, arg2);
				if ((int)logData.Level == 5 && logData.Message == "Requires the authentication.")
				{
					websocketAuthenticationFailure = true;
				}
			};
			if (!string.IsNullOrWhiteSpace(serverPassword))
			{
				clientSocket.SetCredentials("nebula-player", serverPassword, true);
			}
			websocketAuthenticationFailure = false;
			clientSocket.Connect();
			((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = false;
			if (Config.Options.RememberLastIP)
			{
				Config.Options.LastIP = ServerEndpoint.ToString();
				Config.SaveOptions();
			}
			if (Config.Options.RememberLastClientPassword && !string.IsNullOrWhiteSpace(serverPassword))
			{
				Config.Options.LastClientPassword = serverPassword;
				Config.SaveOptions();
			}
			try
			{
				NebulaModAPI.OnMultiplayerSessionChange(true);
				NebulaModAPI.OnMultiplayerGameStarted?.Invoke();
			}
			catch (Exception ex)
			{
				Log.Error("NebulaModAPI.OnMultiplayerGameStarted error:\n" + ex);
			}
		}

		public void Stop()
		{
			WebSocket obj = clientSocket;
			if (obj != null)
			{
				obj.Close((ushort)2001, "Player left the game");
			}
			Config.LoadOptions();
			try
			{
				NebulaModAPI.OnMultiplayerSessionChange(false);
				NebulaModAPI.OnMultiplayerGameEnded?.Invoke();
			}
			catch (Exception ex)
			{
				Log.Error("NebulaModAPI.OnMultiplayerGameEnded error:\n" + ex);
			}
		}

		public void Dispose()
		{
			Stop();
			GC.SuppressFinalize(this);
		}

		public void SendPacket<T>(T packet) where T : class, new()
		{
			NebulaConnection obj = serverConnection;
			if (obj != null)
			{
				obj.SendPacket<T>(packet);
			}
		}

		public void SendToMatching<T>(T packet, Predicate<INebulaPlayer> condition) where T : class, new()
		{
			throw new NotImplementedException();
		}

		public void SendPacketExclude<T>(T packet, INebulaConnection exclude) where T : class, new()
		{
			throw new NotImplementedException();
		}

		public void SendPacketToLocalStar<T>(T packet) where T : class, new()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			NebulaConnection obj = serverConnection;
			if (obj != null)
			{
				obj.SendPacket<StarBroadcastPacket>(new StarBroadcastPacket(PacketProcessor.Write<T>(packet), GameMain.data.localStar?.id ?? (-1)));
			}
		}

		public void SendPacketToLocalPlanet<T>(T packet) where T : class, new()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			NebulaConnection obj = serverConnection;
			if (obj != null)
			{
				obj.SendPacket<PlanetBroadcastPacket>(new PlanetBroadcastPacket(PacketProcessor.Write<T>(packet), GameMain.data.localPlanet?.id ?? (-1)));
			}
		}

		public void SendPacketToPlanet<T>(T packet, int planetId) where T : class, new()
		{
			throw new NotImplementedException();
		}

		public void SendPacketToStar<T>(T packet, int starId) where T : class, new()
		{
			throw new NotImplementedException();
		}

		public void SendPacketToStarExclude<T>(T packet, int starId, INebulaConnection exclude) where T : class, new()
		{
			throw new NotImplementedException();
		}

		public void Update()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			PacketProcessor.ProcessPacketQueue();
			if (Multiplayer.Session.IsGameLoaded)
			{
				mechaSynchonizationTimer += Time.deltaTime;
				if (mechaSynchonizationTimer > 30f)
				{
					this.SendPacket<PlayerMechaData>(new PlayerMechaData(GameMain.mainPlayer));
					mechaSynchonizationTimer = 0f;
				}
				gameStateUpdateTimer += Time.deltaTime;
				if (gameStateUpdateTimer >= 1f)
				{
					if (!GameMain.isFullscreenPaused)
					{
						this.SendPacket<GameStateRequest>(new GameStateRequest());
					}
					gameStateUpdateTimer = 0f;
				}
			}
			fragmentUpdateTimer += Time.deltaTime;
			if (fragmentUpdateTimer >= 0.1f)
			{
				if (GameStatesManager.FragmentSize > 0)
				{
					GameStatesManager.UpdateBufferLength(GetFragmentBufferLength());
				}
				fragmentUpdateTimer = 0f;
			}
		}

		private void ClientSocket_OnMessage(object sender, MessageEventArgs e)
		{
			if (!Multiplayer.IsLeavingGame)
			{
				PacketProcessor.EnqueuePacketForProcessing(e.RawData, (object)serverConnection);
			}
		}

		private void ClientSocket_OnOpen(object sender, EventArgs e)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			DisableNagleAlgorithm(clientSocket);
			Log.Info("Server connection established");
			ref NebulaConnection reference = ref serverConnection;
			WebSocket obj = clientSocket;
			IPEndPoint serverEndpoint = ServerEndpoint;
			INetPacketProcessor packetProcessor = PacketProcessor;
			reference = new NebulaConnection(obj, (EndPoint)serverEndpoint, (NebulaNetPacketProcessor)(object)((packetProcessor is NebulaNetPacketProcessor) ? packetProcessor : null));
			this.SendPacket<LobbyRequest>(new LobbyRequest(CryptoUtils.GetPublicKey(CryptoUtils.GetOrCreateUserCert()), (!string.IsNullOrWhiteSpace(Config.Options.Nickname)) ? Config.Options.Nickname : ((AccountData)(ref GameMain.data.account)).userName));
		}

		private void ClientSocket_OnClose(object sender, CloseEventArgs e)
		{
			serverConnection = null;
			UnityDispatchQueue.RunOnMainThread((Action)delegate
			{
				if (e.Code != 2001)
				{
					MultiplayerSession session = Multiplayer.Session;
					if (session != null && session.IsGameLoaded)
					{
						GameMain.instance._paused = true;
					}
					switch (e.Code)
					{
					case 2500:
						InGamePopup.ShowWarning(Localization.Translate("Mod Mismatch"), string.Format(Localization.Translate("You are missing mod {0}"), e.Reason), Localization.Translate("OK"), (Action)Multiplayer.LeaveGame);
						return;
					case 2501:
						InGamePopup.ShowWarning(Localization.Translate("Mod Mismatch"), string.Format(Localization.Translate("Server is missing mod {0}"), e.Reason), Localization.Translate("OK"), (Action)Multiplayer.LeaveGame);
						return;
					case 2002:
					{
						string[] array = e.Reason.Split(new char[1] { ';' });
						InGamePopup.ShowWarning(Localization.Translate("Mod Version Mismatch"), string.Format(Localization.Translate("Your mod {0} version is not the same as the Host version.\nYou:{1} - Remote:{2}"), array[0], array[1], array[2]), Localization.Translate("OK"), (Action)Multiplayer.LeaveGame);
						return;
					}
					case 2003:
					{
						string[] array2 = e.Reason.Split(new char[1] { ';' });
						InGamePopup.ShowWarning(Localization.Translate("Game Version Mismatch"), string.Format(Localization.Translate("Your version of the game is not the same as the one used by the Host.\nYou:{0} - Remote:{1}"), array2[0], array2[1]), Localization.Translate("OK"), (Action)Multiplayer.LeaveGame);
						return;
					}
					case 1002:
						if (websocketAuthenticationFailure)
						{
							InGamePopup.AskInput(Localization.Translate("Server Requires Password"), Localization.Translate("Server is protected. Please enter the correct password:"), (ContentType)7, serverPassword, (Action<string>)delegate(string password)
							{
								Multiplayer.ShouldReturnToJoinMenu = false;
								Multiplayer.LeaveGame();
								Multiplayer.ShouldReturnToJoinMenu = true;
								Multiplayer.JoinGame((IClient)(object)new Client(ServerEndpoint, password));
							}, (Action)Multiplayer.LeaveGame);
							return;
						}
						break;
					case 2000:
						InGamePopup.ShowWarning(Localization.Translate("Server Busy"), Localization.Translate("Server is not ready to join. Please try again later."), Localization.Translate("OK"), (Action)Multiplayer.LeaveGame);
						return;
					}
					if (Multiplayer.Session != null && (Multiplayer.Session.IsGameLoaded || Multiplayer.Session.IsInLobby))
					{
						InGamePopup.ShowWarning(Localization.Translate("Connection Lost"), Localization.Translate("You have been disconnected from the server.") + "\n" + e.Reason, "Quit", (Action)Multiplayer.LeaveGame);
						if (Multiplayer.Session.IsInLobby)
						{
							Multiplayer.ShouldReturnToJoinMenu = false;
							Multiplayer.Session.IsInLobby = false;
							UIRoot.instance.galaxySelect.CancelSelect();
						}
					}
					else
					{
						Log.Warn("Disconnect code: " + e.Code + ", reason:" + e.Reason);
						InGamePopup.ShowWarning(Localization.Translate("Server Unavailable"), Localization.Translate("Could not reach the server, please try again later."), Localization.Translate("OK"), (Action)Multiplayer.LeaveGame);
					}
				}
			});
		}

		private static void DisableNagleAlgorithm(WebSocket socket)
		{
			TcpClient tcpClient = AccessTools.FieldRefAccess<WebSocket, TcpClient>("_tcpClient").Invoke(socket);
			if (tcpClient != null)
			{
				tcpClient.NoDelay = true;
			}
		}

		private int GetFragmentBufferLength()
		{
			return (int)(fragmentsBufferRef.Invoke(clientSocket)?.Length ?? 0);
		}
	}
	public class Server : IServer, INetworkProvider, IDisposable
	{
		private const float GAME_RESEARCH_UPDATE_INTERVAL = 2f;

		private const float STATISTICS_UPDATE_INTERVAL = 1f;

		private const float LAUNCH_UPDATE_INTERVAL = 4f;

		private const float DYSONSPHERE_UPDATE_INTERVAL = 2f;

		private const float WARNING_UPDATE_INTERVAL = 1f;

		private readonly bool loadSaveFile;

		private float dysonLaunchUpateTimer = 1f;

		private float dysonSphereUpdateTimer;

		private float gameResearchHashUpdateTimer;

		private NgrokManager ngrokManager;

		private float productionStatisticsUpdateTimer;

		private WebSocketServer socket;

		private float warningUpdateTimer;

		private ConcurrentQueue<ushort> PlayerIdPool = new ConcurrentQueue<ushort>();

		private int highestPlayerID;

		public INetPacketProcessor PacketProcessor { get; set; } = (INetPacketProcessor)new NebulaNetPacketProcessor();


		public ConcurrentPlayerCollection Players { get; } = new ConcurrentPlayerCollection();


		public ushort Port { get; set; }

		public string NgrokAddress => ngrokManager.NgrokAddress;

		public bool NgrokActive => ngrokManager.IsNgrokActive();

		public bool NgrokEnabled => ngrokManager.NgrokEnabled;

		public string NgrokLastErrorCode => ngrokManager.NgrokLastErrorCode;

		public event EventHandler<INebulaConnection> Connected;

		public event EventHandler<INebulaConnection> Disconnected;

		public Server(ushort port, bool loadSaveFile = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			Port = port;
			this.loadSaveFile = loadSaveFile;
		}

		internal void OnSocketConnection(INebulaConnection conn)
		{
			//IL_0049: 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_0051: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			ushort nextPlayerId = GetNextPlayerId();
			PlanetData val = GameMain.galaxy.PlanetById(GameMain.galaxy.birthPlanetId);
			Double3 val2 = default(Double3);
			((Double3)(ref val2))..ctor(val.uPosition.x, val.uPosition.y, val.uPosition.z);
			PlayerData val3 = new PlayerData(nextPlayerId, -1, (string)null, default(Float3), val2, default(Float3), default(Float3));
			conn.ConnectionStatus = (EConnectionStatus)1;
			INebulaPlayer val4 = (INebulaPlayer)new NebulaPlayer(conn, (IPlayerData)(object)val3);
			if (!Players.TryAdd(conn, val4))
			{
				throw new InvalidOperationException($"Connection {conn.Id} already exists!");
			}
			this.Connected?.Invoke(this, conn);
		}

		private ushort GetNextPlayerId()
		{
			if (!PlayerIdPool.TryDequeue(out var result))
			{
				return (ushort)Interlocked.Increment(ref highestPlayerID);
			}
			return result;
		}

		internal void OnSocketDisconnection(INebulaConnection conn)
		{
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Invalid comparison between Unknown and I4
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Invalid comparison between Unknown and I4
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			MultiplayerSession session = Multiplayer.Session;
			session.NumPlayers -= 1;
			DiscordManager.UpdateRichPresence((string)null, (string)null, false, false);
			INebulaPlayer val = default(INebulaPlayer);
			Players.TryRemove(conn, ref val);
			if (val == null)
			{
				Log.Warn("Player is null - Disconnect logic NOT CALLED!");
				if (!Config.Options.SyncSoil)
				{
					return;
				}
				GameMain.mainPlayer.sandCount = Multiplayer.Session.LocalPlayer.Data.Mecha.SandCount;
				IReadOnlyDictionary<INebulaConnection, INebulaPlayer> connected = Players.Connected;
				foreach (KeyValuePair<INebulaConnection, INebulaPlayer> item in connected)
				{
					Player mainPlayer = GameMain.mainPlayer;
					mainPlayer.sandCount += item.Value.Data.Mecha.SandCount;
				}
				UIRoot.instance.uiGame.OnSandCountChanged(GameMain.mainPlayer.sandCount, GameMain.mainPlayer.sandCount - Multiplayer.Session.LocalPlayer.Data.Mecha.SandCount);
				this.SendPacket<PlayerSandCount>(new PlayerSandCount(GameMain.mainPlayer.sandCount, false));
				return;
			}
			this.SendPacketExclude<PlayerDisconnected>(new PlayerDisconnected(val.Id, Multiplayer.Session.NumPlayers), conn);
			if ((int)conn.ConnectionStatus == 3)
			{
				SimulatedWorld.OnPlayerLeftGame(val);
			}
			PlayerIdPool.Enqueue(val.Id);
			Multiplayer.Session.PowerTowers.ResetAndBroadcast();
			Multiplayer.Session.Statistics.UnRegisterPlayer(val.Id);
			Multiplayer.Session.DysonSpheres.UnRegisterPlayer(conn);
			int count = Players.Syncing.Count;
			if ((int)conn.ConnectionStatus == 2 && count == 0)
			{
				this.SendPacket<SyncComplete>(new SyncComplete());
				Multiplayer.Session.World.OnAllPlayersSyncCompleted();
				this.Disconnected?.Invoke(this, conn);
			}
		}

		public void Start()
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Expected O, but got Unknown
			SaveManager.LoadServerData(loadSaveFile);
			foreach (Assembly nebulaAssembly in AssembliesUtils.GetNebulaAssemblies())
			{
				INetPacketProcessor packetProcessor = PacketProcessor;
				PacketUtils.RegisterAllPacketNestedTypesInAssembly(nebulaAssembly, (NetPacketProcessor)(object)((packetProcessor is NebulaNetPacketProcessor) ? packetProcessor : null));
			}
			INetPacketProcessor packetProcessor2 = PacketProcessor;
			PacketUtils.RegisterAllPacketProcessorsInCallingAssembly((NetPacketProcessor)(object)((packetProcessor2 is NebulaNetPacketProcessor) ? packetProcessor2 : null), true);
			foreach (Assembly targetAssembly in NebulaModAPI.TargetAssemblies)
			{
				INetPacketProcessor packetProcessor3 = PacketProcessor;
				PacketUtils.RegisterAllPacketNestedTypesInAssembly(targetAssembly, (NetPacketProcessor)(object)((packetProcessor3 is NebulaNetPacketProcessor) ? packetProcessor3 : null));
				INetPacketProcessor packetProcessor4 = PacketProcessor;
				PacketUtils.RegisterAllPacketProcessorsInAssembly(targetAssembly, (NetPacketProcessor)(object)((packetProcessor4 is NebulaNetPacketProcessor) ? packetProcessor4 : null), true);
			}
			if (Config.Options.EnableUPnpOrPmpSupport)
			{
				Task.Run(async delegate
				{
					NatDiscoverer val2 = new NatDiscoverer();
					try
					{
						await (await val2.DiscoverDeviceAsync()).CreatePortMapAsync(new Mapping((Protocol)0, (int)Port, (int)Port, "DSP nebula"));
						Log.Info($"Successfully created UPnp or Pmp port mapping for {Port}");
					}
					catch (NatDeviceNotFoundException)
					{
						Log.WarnInform(Localization.Translate("No UPnp or Pmp compatible/enabled NAT device found"));
					}
					catch (MappingException)
					{
						Log.WarnInform(Localization.Translate("Could not create UPnp or Pmp port mapping"));
					}
				});
			}
			ngrokManager = new NgrokManager(Port);
			WebSocketServer val = new WebSocketServer(IPAddress.IPv6Any, (int)Port);
			val.Log.Level = (LogLevel)1;
			val.Log.Output = Log.SocketOutput;
			val.AllowForwardedRequest = true;
			socket = val;
			if (!string.IsNullOrWhiteSpace(Config.Options.ServerPassword))
			{
				socket.AuthenticationSchemes = (AuthenticationSchemes)8;
				socket.UserCredentialsFinder = delegate(IIdentity id)
				{
					//IL_0021: Unknown result type (might be due to invalid IL or missing references)
					//IL_0027: Expected O, but got Unknown
					string name = id.Name;
					return (name == "nebula-player") ? new NetworkCredential(name, Config.Options.ServerPassword) : ((NetworkCredential)null);
				};
			}
			DisableNagleAlgorithm(socket);
			INetPacketProcessor packetProcessor5 = PacketProcessor;
			WebSocketService.PacketProcessor = (NebulaNetPacketProcessor)(object)((packetProcessor5 is NebulaNetPacketProcessor) ? packetProcessor5 : null);
			WebSocketService.Server = this;
			socket.AddWebSocketService<WebSocketService>("/socket", (Action<WebSocketService>)delegate
			{
				new WebSocketService();
			});
			try
			{
				socket.WaitTime = TimeSpan.FromSeconds(20.0);
				socket.KeepClean = Config.Options.CleanupInactiveSessions;
				socket.Start();
			}
			catch (InvalidOperationException ex)
			{
				InGamePopup.ShowError("Error", Localization.Translate("An error occurred while hosting the game: ") + ex.Message, Localization.Translate("Close"), (Action)null);
				Stop();
				Multiplayer.LeaveGame();
				return;
			}
			((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = true;
			((LocalPlayer)Multiplayer.Session.LocalPlayer).SetPlayerData(new PlayerData(GetNextPlayerId(), GameMain.localPlanet?.id ?? (-1), (!string.IsNullOrWhiteSpace(Config.Options.Nickname)) ? Config.Options.Nickname : ((AccountData)(ref GameMain.data.account)).userName, default(Float3), default(Double3), default(Float3), default(Float3)), loadSaveFile);
			Task.Run(async delegate
			{
				if (ngrokManager.IsNgrokActive())
				{
					string text = await ngrokManager.GetNgrokAddressAsync();
					DiscordManager.UpdateRichPresence(text, (string)null, false, true);
					if (Multiplayer.IsDedicated)
					{
						Log.Info(">> Ngrok address: " + text);
					}
				}
				else
				{
					string text2 = (((int)Config.Options.IPConfiguration == 2) ? string.Empty : (await IPUtils.GetWANv4Address()));
					string text3 = (((int)Config.Options.IPConfiguration == 1) ? string.Empty : (await IPUtils.GetWANv6Address()));
					DiscordManager.UpdateRichPresence(text2 + ";" + text3 + ";" + $"{Port}", (string)null, false, true);
				}
			});
			try
			{
				NebulaModAPI.OnMultiplayerSessionChange(true);
				NebulaModAPI.OnMultiplayerGameStarted?.Invoke();
			}
			catch (Exception ex2)
			{
				Log.Error("NebulaModAPI.OnMultiplayerGameStarted error:\n" + ex2);
			}
		}

		public void Stop()
		{
			WebSocketServer obj = socket;
			if (obj != null)
			{
				obj.Stop();
			}
			ngrokManager?.StopNgrok();
			try
			{
				NebulaModAPI.OnMultiplayerSessionChange(false);
				NebulaModAPI.OnMultiplayerGameEnded?.Invoke();
			}
			catch (Exception ex)
			{
				Log.Error("NebulaModAPI.OnMultiplayerGameEnded error:\n" + ex);
			}
		}

		public void Disconnect(INebulaConnection conn, DisconnectionReason reason, string reasonMessage = "")
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			INebulaPlayer val = default(INebulaPlayer);
			Players.TryRemove(conn, ref val);
			if (Encoding.UTF8.GetBytes(reasonMessage).Length <= 123)
			{
				((NebulaConnection)conn).peerSocket.Close((ushort)reason, reasonMessage);
				return;
			}
			throw new ArgumentException("Reason string cannot take up more than 123 bytes");
		}

		public void Dispose()
		{
			Stop();
			GC.SuppressFinalize(this);
		}

		public void SendToPlayers<T>(IEnumerable<KeyValuePair<INebulaConnection, INebulaPlayer>> players, T packet) where T : class, new()
		{
			foreach (KeyValuePair<INebulaConnection, INebulaPlayer> player in players)
			{
				player.Key.SendPacket<T>(packet);
			}
		}

		public void SendPacket<T>(T packet) where T : class, new()
		{
			SendToPlayers(Players.Connected, packet);
		}

		public void SendToMatching<T>(T packet, Predicate<INebulaPlayer> condition) where T : class, new()
		{
			IEnumerable<KeyValuePair<INebulaConnection, INebulaPlayer>> players = Players.Connected.Where((KeyValuePair<INebulaConnection, INebulaPlayer> kvp) => condition(kvp.Value));
			SendToPlayers(players, packet);
		}

		public void SendPacketToStar<T>(T packet, int starId) where T : class, new()
		{
			SendToMatching(packet, (INebulaPlayer p) => p.Data.LocalStarId == starId);
		}

		public void SendPacketToLocalStar<T>(T packet) where T : class, new()
		{
			int starId = GameMain.data.localStar?.id ?? (-1);
			SendPacketToStar(packet, starId);
		}

		public void SendPacketToPlanet<T>(T packet, int planetId) where T : class, new()
		{
			SendToMatching(packet, (INebulaPlayer p) => p.Data.LocalPlanetId == planetId);
		}

		public void SendPacketToLocalPlanet<T>(T packet) where T : class, new()
		{
			int planetId = GameMain.data.localPlanet?.id ?? (-1);
			SendPacketToPlanet(packet, planetId);
		}

		public void SendPacketExclude<T>(T packet, INebulaConnection exclude) where T : class, new()
		{
			SendToMatching(packet, (INebulaPlayer p) => !((IEquatable<INebulaConnection>)p.Connection).Equals(exclude));
		}

		public void SendPacketToStarExclude<T>(T packet, int starId, INebulaConnection exclude) where T : class, new()
		{
			SendToMatching(packet, (INebulaPlayer p) => p.Data.LocalStarId == starId && !((IEquatable<INebulaConnection>)p.Connection).Equals(exclude));
		}

		public void Update()
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			PacketProcessor.ProcessPacketQueue();
			if (!Multiplayer.Session.IsGameLoaded)
			{
				return;
			}
			gameResearchHashUpdateTimer += Time.deltaTime;
			productionStatisticsUpdateTimer += Time.deltaTime;
			dysonLaunchUpateTimer += Time.deltaTime;
			dysonSphereUpdateTimer += Time.deltaTime;
			warningUpdateTimer += Time.deltaTime;
			if (gameResearchHashUpdateTimer > 2f)
			{
				gameResearchHashUpdateTimer = 0f;
				if (GameMain.data.history.currentTech != 0)
				{
					TechState val = GameMain.data.history.techStates[GameMain.data.history.currentTech];
					this.SendPacket<GameHistoryResearchUpdatePacket>(new GameHistoryResearchUpdatePacket(GameMain.data.history.currentTech, val.hashUploaded, val.hashNeeded, GameMain.statistics.techHashedFor10Frames, GameMain.data.history.techQueueLength));
				}
			}
			if (productionStatisticsUpdateTimer > 1f)
			{
				productionStatisticsUpdateTimer = 0f;
				Multiplayer.Session.Statistics.SendBroadcastIfNeeded();
			}
			if (dysonLaunchUpateTimer > 4f)
			{
				dysonLaunchUpateTimer = 0f;
				Multiplayer.Session.Launch.SendBroadcastIfNeeded();
			}
			if (dysonSphereUpdateTimer > 2f)
			{
				dysonSphereUpdateTimer = 0f;
				Multiplayer.Session.DysonSpheres.UpdateSphereStatusIfNeeded();
			}
			if (warningUpdateTimer > 1f)
			{
				warningUpdateTimer = 0f;
				Multiplayer.Session.Warning.SendBroadcastIfNeeded();
			}
		}

		private static void DisableNagleAlgorithm(WebSocketServer socketServer)
		{
			TcpListener tcpListener = AccessTools.FieldRefAccess<WebSocketServer, TcpListener>("_listener").Invoke(socketServer);
			tcpListener.Server.NoDelay = true;
		}
	}
}
namespace NebulaNetwork.PacketProcessors.Warning
{
	[RegisterPacketProcessor]
	internal class WarningDataProcessor : PacketProcessor<WarningDataPacket>
	{
		protected override void ProcessPacket(WarningDataPacket packet, NebulaConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			Multiplayer.Session.Warning.TickData = packet.Tick;
			Reader val = new Reader(packet.BinaryData);
			try
			{
				Multiplayer.Session.Warning.ImportBinaryData(val.BinaryReader, packet.ActiveWarningCount);
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}
	}
	[RegisterPacketProcessor]
	internal class WarningDataRequestProcessor : PacketProcessor<WarningDataRequest>
	{
		protected override void ProcessPacket(WarningDataRequest packet, NebulaConnection conn)
		{
			Multiplayer.Session.Warning.HandleRequest(packet, conn);
		}
	}
	[RegisterPacketProcessor]
	internal class WarningSignalProcessor : PacketProcessor<WarningSignalPacket>
	{
		protected override void ProcessPacket(WarningSignalPacket packet, NebulaConnection conn)
		{
			WarningSystem warningSystem = GameMain.data.warningSystem;
			Array.Clear(warningSystem.warningCounts, 0, warningSystem.warningCounts.Length);
			Array.Clear(warningSystem.warningSignals, 0, warningSystem.warningSignalCount);
			warningSystem.warningSignalCount = packet.SignalCount;
			for (int i = 0; i < packet.SignalCount; i++)
			{
				int num = packet.Signals[i];
				warningSystem.warningSignals[i] = num;
				warningSystem.warningCounts[num] = packet.Counts[i];
			}
			Multiplayer.Session.Warning.TickSignal = packet.Tick;
		}
	}
}
namespace NebulaNetwork.PacketProcessors.Universe
{
	[RegisterPacketProcessor]
	internal class DysonLaunchDataProcessor : PacketProcessor<DysonLaunchDataPacket>
	{
		protected override void ProcessPacket(DysonLaunchDataPacket packet, NebulaConnection conn)
		{
			if (!((BasePacketProcessor<DysonLaunchDataPacket>)this).IsHost)
			{
				Multiplayer.Session.Launch.ImportPacket(packet);
			}
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSailDataProcessor : PacketProcessor<DysonSailDataPacket>
	{
		protected override void ProcessPacket(DysonSailDataPacket packet, NebulaConnection conn)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
			if (val != null)
			{
				using (Multiplayer.Session.DysonSpheres.IncomingDysonSwarmPacket.On())
				{
					DysonSail val2 = default(DysonSail);
					val2.px = packet.px;
					val2.py = packet.py;
					val2.pz = packet.pz;
					val2.vx = packet.vx;
					val2.vy = packet.vy;
					val2.vz = packet.vz;
					val2.gs = packet.gs;
					val.swarm.AddSolarSail(val2, packet.OrbitId, packet.ExpiryTime);
				}
				if (((BasePacketProcessor<DysonSailDataPacket>)this).IsHost)
				{
					Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSailDataPacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
				}
			}
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSphereDataProcessor : PacketProcessor<DysonSphereData>
	{
		protected override void ProcessPacket(DysonSphereData packet, NebulaConnection conn)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0024: Expected I4, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			if (((BasePacketProcessor<DysonSphereData>)this).IsHost)
			{
				return;
			}
			DysonSphereRespondEvent @event = packet.Event;
			switch (@event - 1)
			{
			case 0:
			{
				UIComboBox dysonBox2 = UIRoot.instance.uiGame.dysonEditor.controlPanel.topFunction.dysonBox;
				using (BinaryReader binaryReader = new Reader(packet.BinaryData).BinaryReader)
				{
					dysonBox2.Items = new List<string>();
					dysonBox2.ItemsData = new List<int>();
					int num2 = binaryReader.ReadInt32();
					for (int i = 0; i < num2; i++)
					{
						int num3 = binaryReader.ReadInt32();
						dysonBox2.Items.Add(GameMain.galaxy.stars[num3].displayName);
						dysonBox2.ItemsData.Add(num3);
					}
				}
				int num4 = dysonBox2.ItemsData.FindIndex((int x) => x == UIRoot.instance.uiGame.dysonEditor.selection.viewStar?.index);
				dysonBox2.itemIndex = ((num4 >= 0) ? num4 : 0);
				break;
			}
			case 1:
			{
				GameStatesManager.FragmentSize = 0;
				GameMain.data.dysonSpheres[packet.StarIndex] = new DysonSphere();
				GameMain.data.statistics.production.Init(GameMain.data);
				if (GameMain.data.statistics.production.factoryStatPool[0] == null)
				{
					GameMain.data.statistics.production.factoryStatPool[0] = new FactoryProductionStat();
					GameMain.data.statistics.production.factoryStatPool[0].Init();
				}
				GameMain.data.dysonSpheres[packet.StarIndex].Init(GameMain.data, GameMain.data.galaxy.stars[packet.StarIndex]);
				StarData val = GameMain.galaxy.stars[packet.StarIndex];
				Log.Info($"Parsing {packet.BinaryData.Length} bytes of data for DysonSphere {val.name} (INDEX: {val.id})");
				Reader val2 = new Reader(packet.BinaryData);
				try
				{
					GameMain.data.dysonSpheres[packet.StarIndex].Import(val2.BinaryReader);
				}
				finally
				{
					((IDisposable)val2)?.Dispose();
				}
				if (((ManualBehaviour)UIRoot.instance.uiGame.dysonEditor).active)
				{
					UIRoot.instance.uiGame.dysonEditor.selection.SetViewStar(GameMain.galaxy.stars[packet.StarIndex]);
					UIComboBox dysonBox = UIRoot.instance.uiGame.dysonEditor.controlPanel.topFunction.dysonBox;
					int num = dysonBox.ItemsData.FindIndex((int x) => x == UIRoot.instance.uiGame.dysonEditor.selection.viewStar?.index);
					dysonBox.itemIndex = ((num >= 0) ? num : 0);
				}
				if (Multiplayer.Session.IsGameLoaded)
				{
					InGamePopup.FadeOut();
				}
				Multiplayer.Session.DysonSpheres.RequestingIndex = -1;
				Multiplayer.Session.DysonSpheres.IsNormal = true;
				try
				{
					NebulaModAPI.OnDysonSphereLoadFinished?.Invoke(val.index);
					break;
				}
				catch (Exception ex)
				{
					Log.Error("NebulaModAPI.OnDysonSphereLoadFinished error:\n" + ex);
					break;
				}
			}
			case 2:
				Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
				break;
			default:
			{
				DysonSphereRespondEvent event2 = packet.Event;
				throw new ArgumentOutOfRangeException("packet", "Unknown DysonSphereRespondEvent: " + ((object)(DysonSphereRespondEvent)(ref event2)).ToString());
			}
			}
		}
	}
	[RegisterPacketProcessor]
	public class DysonSphereRequestProcessor : PacketProcessor<DysonSphereLoadRequest>
	{
		protected override void ProcessPacket(DysonSphereLoadRequest packet, NebulaConnection conn)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0028: Expected I4, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Expected O, but got Unknown
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Expected O, but got Unknown
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			if (((BasePacketProcessor<DysonSphereLoadRequest>)this).IsClient)
			{
				return;
			}
			DysonSphereRequestEvent @event = packet.Event;
			switch (@event - 1)
			{
			case 0:
			{
				Writer val4 = new Writer();
				try
				{
					List<int> list = new List<int>();
					for (int i = 0; i < GameMain.data.dysonSpheres.Length; i++)
					{
						if (GameMain.data.dysonSpheres[i] != null)
						{
							list.Add(i);
						}
					}
					val4.BinaryWriter.Write(list.Count);
					foreach (int item in list)
					{
						val4.BinaryWriter.Write(item);
					}
					conn.SendPacket<DysonSphereData>(new DysonSphereData(packet.StarIndex, val4.CloseAndGetBytes(), (DysonSphereRespondEvent)1));
					break;
				}
				finally
				{
					((IDisposable)val4)?.Dispose();
				}
			}
			case 1:
			{
				DysonSphere val = GameMain.data.CreateDysonSphere(packet.StarIndex);
				Writer val3 = new Writer();
				try
				{
					val.Export(val3.BinaryWriter);
					byte[] array2 = val3.CloseAndGetBytes();
					Log.Info($"Sent {array2.Length} bytes of data for DysonSphereData (INDEX: {packet.StarIndex})");
					conn.SendPacket<FragmentInfo>(new FragmentInfo(array2.Length));
					conn.SendPacket<DysonSphereData>(new DysonSphereData(packet.StarIndex, array2, (DysonSphereRespondEvent)2));
					Multiplayer.Session.DysonSpheres.RegisterPlayer((INebulaConnection)(object)conn, packet.StarIndex);
					break;
				}
				finally
				{
					((IDisposable)val3)?.Dispose();
				}
			}
			case 2:
				Multiplayer.Session.DysonSpheres.UnRegisterPlayer((INebulaConnection)(object)conn, packet.StarIndex);
				break;
			case 3:
			{
				if (packet.StarIndex < 0 || packet.StarIndex >= GameMain.data.galaxy.starCount)
				{
					break;
				}
				DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
				if (val == null)
				{
					break;
				}
				Writer val2 = new Writer();
				try
				{
					val.Export(val2.BinaryWriter);
					byte[] array = val2.CloseAndGetBytes();
					Log.Info($"Sent {array.Length} bytes of data for DysonSphereData (INDEX: {packet.StarIndex})");
					conn.SendPacket<FragmentInfo>(new FragmentInfo(array.Length));
					conn.SendPacket<DysonSphereData>(new DysonSphereData(packet.StarIndex, array, (DysonSphereRespondEvent)2));
					Multiplayer.Session.DysonSpheres.RegisterPlayer((INebulaConnection)(object)conn, packet.StarIndex);
					break;
				}
				finally
				{
					((IDisposable)val2)?.Dispose();
				}
			}
			default:
			{
				DysonSphereRequestEvent event2 = packet.Event;
				throw new ArgumentOutOfRangeException("packet", "Unknown DysonSphereRequestEvent: " + ((object)(DysonSphereRequestEvent)(ref event2)).ToString());
			}
			}
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSphereStatusProcessor : PacketProcessor<DysonSphereStatusPacket>
	{
		protected override void ProcessPacket(DysonSphereStatusPacket packet, NebulaConnection conn)
		{
			DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
			if (!((BasePacketProcessor<DysonSphereStatusPacket>)this).IsHost && val != null)
			{
				val.grossRadius = packet.GrossRadius;
				val.energyReqCurrentTick = packet.EnergyReqCurrentTick;
				val.energyGenCurrentTick = packet.EnergyGenCurrentTick;
				val.energyGenOriginalCurrentTick = (long)((double)val.energyGenCurrentTick / val.energyDFHivesDebuffCoef);
			}
		}
	}
	[RegisterPacketProcessor]
	internal class NameInputProcessor : PacketProcessor<NameInputPacket>
	{
		protected override void ProcessPacket(NameInputPacket packet, NebulaConnection conn)
		{
			if (((BasePacketProcessor<NameInputPacket>)this).IsHost)
			{
				INebulaPlayer val = base.Players.Get((INebulaConnection)(object)conn, (EConnectionStatus)3);
				if (val != null)
				{
					((INetworkProvider)base.Server).SendPacketExclude<NameInputPacket>(packet, (INebulaConnection)(object)conn);
				}
			}
			using (Multiplayer.Session.Factories.IsIncomingRequest.On())
			{
				GalaxyData val2 = (Multiplayer.Session.IsInLobby ? UIRoot.instance.galaxySelect.starmap.galaxyData : GameMain.galaxy);
				if (val2 == null)
				{
					return;
				}
				for (int i = 0; i < packet.Names.Length; i++)
				{
					if (packet.StarIds[i] != -1)
					{
						StarData val3 = val2.StarById(packet.StarIds[i]);
						val3.overrideName = packet.Names[i];
						val3.NotifyOnDisplayNameChange();
					}
					else
					{
						PlanetData val4 = val2.PlanetById(packet.PlanetIds[i]);
						val4.overrideName = packet.Names[i];
						val4.NotifyOnDisplayNameChange();
					}
				}
				val2.NotifyAstroNameChange();
				if (Multiplayer.Session.IsInLobby)
				{
					UIRoot.instance.galaxySelect.starmap.OnGalaxyDataReset();
				}
			}
		}
	}
}
namespace NebulaNetwork.PacketProcessors.Universe.Editor
{
	[RegisterPacketProcessor]
	internal class DysonBlueprintProcessor : PacketProcessor<DysonBlueprintPacket>
	{
		protected override void ProcessPacket(DysonBlueprintPacket packet, NebulaConnection conn)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
			{
				DysonSphereLayer layer = val.GetLayer(packet.LayerId);
				string @string = Encoding.ASCII.GetString(packet.BinaryData);
				DysonBlueprintDataIOError val2 = new DysonBlueprintData().FromBase64String(@string, packet.BlueprintType, val, layer);
				if ((int)val2 != 0)
				{
					Log.Warn($"DysonBlueprintData IO error: {val2}");
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
			}
			if (((BasePacketProcessor<DysonBlueprintPacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonBlueprintPacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSphereAddFrameProcessor : PacketProcessor<DysonSphereAddFramePacket>
	{
		protected override void ProcessPacket(DysonSphereAddFramePacket packet, NebulaConnection conn)
		{
			DysonSphere obj = GameMain.data.dysonSpheres[packet.StarIndex];
			DysonSphereLayer val = ((obj != null) ? obj.GetLayer(packet.LayerId) : null);
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
			{
				int num = ((val.frameRecycleCursor > 0) ? val.frameRecycle[val.frameRecycleCursor - 1] : val.frameCursor);
				if (num != packet.FrameId || val.NewDysonFrame(packet.ProtoId, packet.NodeAId, packet.NodeBId, packet.Euler) == 0)
				{
					Log.Warn($"Cannnot add frame[{packet.FrameId}] on layer[{val.id}], starIndex[{packet.StarIndex}]");
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
			}
			if (((BasePacketProcessor<DysonSphereAddFramePacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSphereAddFramePacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
	[RegisterPacketProcessor]
	public class DysonSphereAddLayerProcessor : PacketProcessor<DysonSphereAddLayerPacket>
	{
		protected override void ProcessPacket(DysonSphereAddLayerPacket packet, NebulaConnection conn)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
			{
				if (packet.LayerId != val.QueryLayerId())
				{
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
				val.AddLayer(packet.OrbitRadius, DataStructureExtensions.ToQuaternion(packet.OrbitRotation), packet.OrbitAngularSpeed);
			}
			if (((BasePacketProcessor<DysonSphereAddLayerPacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSphereAddLayerPacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSphereAddNodeProcessor : PacketProcessor<DysonSphereAddNodePacket>
	{
		protected override void ProcessPacket(DysonSphereAddNodePacket packet, NebulaConnection conn)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			DysonSphere obj = GameMain.data.dysonSpheres[packet.StarIndex];
			DysonSphereLayer val = ((obj != null) ? obj.GetLayer(packet.LayerId) : null);
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
			{
				int num = ((val.nodeRecycleCursor > 0) ? val.nodeRecycle[val.nodeRecycleCursor - 1] : val.nodeCursor);
				if (num != packet.NodeId || val.NewDysonNode(packet.NodeProtoId, DataStructureExtensions.ToVector3(packet.Position)) == 0)
				{
					Log.Warn($"Cannnot add node[{packet.NodeId}] on layer[{val.id}], starIndex[{packet.StarIndex}]");
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
			}
			if (((BasePacketProcessor<DysonSphereAddNodePacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSphereAddNodePacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSphereAddShellProcessor : PacketProcessor<DysonSphereAddShellPacket>
	{
		protected override void ProcessPacket(DysonSphereAddShellPacket packet, NebulaConnection conn)
		{
			DysonSphere obj = GameMain.data.dysonSpheres[packet.StarIndex];
			DysonSphereLayer val = ((obj != null) ? obj.GetLayer(packet.LayerId) : null);
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
			{
				int num = ((val.shellRecycleCursor > 0) ? val.shellRecycle[val.shellRecycleCursor - 1] : val.shellCursor);
				if (num != packet.ShellId)
				{
					goto IL_008b;
				}
				int protoId = packet.ProtoId;
				int[] nodeIds = packet.NodeIds;
				List<int> list = new List<int>(nodeIds.Length);
				list.AddRange(nodeIds);
				if (val.NewDysonShell(protoId, list) == 0)
				{
					goto IL_008b;
				}
				goto end_IL_003d;
				IL_008b:
				Log.Warn($"Cannnot add shell[{packet.ShellId}] on layer[{val.id}], starIndex[{packet.StarIndex}]");
				Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
				return;
				end_IL_003d:;
			}
			if (((BasePacketProcessor<DysonSphereAddShellPacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSphereAddShellPacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
	[RegisterPacketProcessor]
	public class DysonSphereColorChangeProcessor : PacketProcessor<DysonSphereColorChangePacket>
	{
		protected override void ProcessPacket(DysonSphereColorChangePacket packet, NebulaConnection conn)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected I4, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
			{
				DysonSphereLayer layer = val.GetLayer(packet.LayerId);
				if (layer == null)
				{
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
				Float4 color = packet.Color;
				Color32 color2 = ((Float4)(ref color)).ToColor32();
				ComponentType type = packet.Type;
				switch ((int)type)
				{
				case 0:
				{
					DysonNode val3 = ((packet.Index < layer.nodeCursor) ? layer.nodePool[packet.Index] : null);
					if (val3 != null)
					{
						val3.color = color2;
						val.UpdateColor(val3);
					}
					break;
				}
				case 1:
				{
					DysonFrame val4 = ((packet.Index < layer.frameCursor) ? layer.framePool[packet.Index] : null);
					if (val4 != null)
					{
						val4.color = color2;
						val.UpdateColor(val4);
					}
					break;
				}
				case 2:
				{
					DysonShell val2 = ((packet.Index < layer.shellCursor) ? layer.shellPool[packet.Index] : null);
					if (val2 != null)
					{
						val2.color = color2;
					}
					break;
				}
				default:
				{
					ComponentType type2 = packet.Type;
					throw new ArgumentOutOfRangeException("packet", "Unknown DysonSphereColorChangePacket type: " + ((object)(ComponentType)(ref type2)).ToString());
				}
				}
			}
			if (((BasePacketProcessor<DysonSphereColorChangePacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSphereColorChangePacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
	[RegisterPacketProcessor]
	public class DysonSphereEditLayerProcessor : PacketProcessor<DysonSphereEditLayerPacket>
	{
		protected override void ProcessPacket(DysonSphereEditLayerPacket packet, NebulaConnection conn)
		{
			//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)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
			{
				DysonSphereLayer layer = val.GetLayer(packet.LayerId);
				if (layer == null)
				{
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
				layer.targetOrbitRotation = DataStructureExtensions.ToQuaternion(packet.OrbitRotation);
				layer.InitOrbitRotation(layer.orbitRotation, layer.targetOrbitRotation);
			}
			if (((BasePacketProcessor<DysonSphereEditLayerPacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSphereEditLayerPacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
	[RegisterPacketProcessor]
	public class DysonSpherePaintCellsProcessor : PacketProcessor<DysonSpherePaintCellsPacket>
	{
		protected override void ProcessPacket(DysonSpherePaintCellsPacket packet, NebulaConnection conn)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
			{
				DysonSphereLayer layer = val.GetLayer(packet.LayerId);
				if (layer == null)
				{
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
				Color32[] array;
				if (layer.cellColors != null)
				{
					Assert.True(layer.cellColors.Length == packet.CellCount);
					array = layer.cellColors;
				}
				else
				{
					array = (Color32[])(object)new Color32[packet.CellCount];
				}
				Float4 paint = packet.Paint;
				Color32 val2 = ((Float4)(ref paint)).ToColor32();
				int[] cursorCells = packet.CursorCells;
				foreach (int num in cursorCells)
				{
					if (num >= 0)
					{
						Color32 val3 = array[num];
						val3.a -= (byte)((val3.a > 127) ? 127 : 0);
						val3.a *= 2;
						Color32 val4 = Color32.Lerp(val3, val2, packet.Strength);
						val4.a /= 2;
						val4.a += (byte)((val2.a > 0) ? (packet.SuperBrightMode ? 127 : 0) : 0);
						array[num] = val4;
					}
				}
				layer.SetPaintingData(array);
			}
			if (((BasePacketProcessor<DysonSpherePaintCellsPacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSpherePaintCellsPacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSphereRemoveFrameProcessor : PacketProcessor<DysonSphereRemoveFramePacket>
	{
		protected override void ProcessPacket(DysonSphereRemoveFramePacket packet, NebulaConnection conn)
		{
			DysonSphere obj = GameMain.data.dysonSpheres[packet.StarIndex];
			DysonSphereLayer val = ((obj != null) ? obj.GetLayer(packet.LayerId) : null);
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
			{
				if (!Check(val, packet))
				{
					Log.Warn($"Cannnot remove frame[{packet.FrameId}] on layer[{val.id}], starIndex[{packet.StarIndex}]");
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
				if (val.framePool[packet.FrameId] != null)
				{
					val.RemoveDysonFrame(packet.FrameId);
					DysonSphereManager.ClearSelection(packet.StarIndex, val.id);
				}
			}
			if (((BasePacketProcessor<DysonSphereRemoveFramePacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSphereRemoveFramePacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}

		private static bool Check(DysonSphereLayer layer, DysonSphereRemoveFramePacket packet)
		{
			if (packet.FrameId < 1 || packet.FrameId >= layer.frameCursor)
			{
				return false;
			}
			DysonFrame frame = layer.framePool[packet.FrameId];
			if (frame == null)
			{
				return true;
			}
			List<int> delShellList = new List<int>();
			foreach (DysonShell item in frame.nodeA.shells.Where((DysonShell shell) => shell.frames.Contains(frame) && !delShellList.Contains(shell.id)))
			{
				delShellList.Add(item.id);
			}
			foreach (DysonShell item2 in frame.nodeB.shells.Where((DysonShell shell) => shell.frames.Contains(frame) && !delShellList.Contains(shell.id)))
			{
				delShellList.Add(item2.id);
			}
			foreach (int item3 in delShellList)
			{
				layer.RemoveDysonShell(item3);
			}
			return true;
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSphereRemoveLayerProcessor : PacketProcessor<DysonSphereRemoveLayerPacket>
	{
		protected override void ProcessPacket(DysonSphereRemoveLayerPacket packet, NebulaConnection conn)
		{
			DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
			if (val != null)
			{
				using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
				{
					val.RemoveLayer(packet.LayerId);
					DysonSphereManager.ClearSelection(packet.StarIndex, -1);
				}
				if (((BasePacketProcessor<DysonSphereRemoveLayerPacket>)this).IsHost)
				{
					Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSphereRemoveLayerPacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
				}
			}
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSphereRemoveNodeProcessor : PacketProcessor<DysonSphereRemoveNodePacket>
	{
		protected override void ProcessPacket(DysonSphereRemoveNodePacket packet, NebulaConnection conn)
		{
			DysonSphere obj = GameMain.data.dysonSpheres[packet.StarIndex];
			DysonSphereLayer val = ((obj != null) ? obj.GetLayer(packet.LayerId) : null);
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
			{
				if (!Check(val, packet))
				{
					Log.Warn($"Cannnot remove node[{packet.NodeId}] on layer[{val.id}], starIndex[{packet.StarIndex}]");
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
				if (val.nodePool[packet.NodeId] != null)
				{
					val.RemoveDysonNode(packet.NodeId);
					DysonSphereManager.ClearSelection(packet.StarIndex, val.id);
				}
			}
			if (((BasePacketProcessor<DysonSphereRemoveNodePacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSphereRemoveNodePacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}

		private static bool Check(DysonSphereLayer layer, DysonSphereRemoveNodePacket packet)
		{
			if (packet.NodeId < 1 || packet.NodeId >= layer.nodeCursor)
			{
				return false;
			}
			DysonNode val = layer.nodePool[packet.NodeId];
			if (val == null)
			{
				return true;
			}
			return val.frames.Count <= 0;
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSphereRemoveShellProcessor : PacketProcessor<DysonSphereRemoveShellPacket>
	{
		protected override void ProcessPacket(DysonSphereRemoveShellPacket packet, NebulaConnection conn)
		{
			DysonSphere obj = GameMain.data.dysonSpheres[packet.StarIndex];
			DysonSphereLayer val = ((obj != null) ? obj.GetLayer(packet.LayerId) : null);
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IsIncomingRequest.On())
			{
				if (packet.ShellId < 1 || packet.ShellId >= val.shellCursor)
				{
					Log.Warn($"Cannnot remove shell[{packet.ShellId}] on layer[{val.id}], starIndex[{packet.StarIndex}]");
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
				if (val.shellPool[packet.ShellId] != null)
				{
					val.RemoveDysonShell(packet.ShellId);
					DysonSphereManager.ClearSelection(packet.StarIndex, val.id);
				}
			}
			if (((BasePacketProcessor<DysonSphereRemoveShellPacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSphereRemoveShellPacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSwarmAddOrbitProcessor : PacketProcessor<DysonSwarmAddOrbitPacket>
	{
		protected override void ProcessPacket(DysonSwarmAddOrbitPacket packet, NebulaConnection conn)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IncomingDysonSwarmPacket.On())
			{
				if (packet.OrbitId != DysonSphereManager.QueryOrbitId(val.swarm))
				{
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
				val.swarm.NewOrbit(packet.Radius, DataStructureExtensions.ToQuaternion(packet.Rotation));
			}
			if (((BasePacketProcessor<DysonSwarmAddOrbitPacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSwarmAddOrbitPacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSwarmEditOrbitProcessor : PacketProcessor<DysonSwarmEditOrbitPacket>
	{
		protected override void ProcessPacket(DysonSwarmEditOrbitPacket packet, NebulaConnection conn)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IncomingDysonSwarmPacket.On())
			{
				if (!val.swarm.OrbitExist(packet.OrbitId))
				{
					Multiplayer.Session.DysonSpheres.HandleDesync(packet.StarIndex, (INebulaConnection)(object)conn);
					return;
				}
				if (packet.Radius >= 0f)
				{
					val.swarm.EditOrbit(packet.OrbitId, packet.Radius, DataStructureExtensions.ToQuaternion(packet.Rotation));
				}
				else
				{
					val.swarm.SetOrbitColor(packet.OrbitId, new Vector4(packet.Color.x, packet.Color.y, packet.Color.z, packet.Color.w));
				}
			}
			if (((BasePacketProcessor<DysonSwarmEditOrbitPacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSwarmEditOrbitPacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
	[RegisterPacketProcessor]
	internal class DysonSwarmRemoveOrbitProcessor : PacketProcessor<DysonSwarmRemoveOrbitPacket>
	{
		protected override void ProcessPacket(DysonSwarmRemoveOrbitPacket packet, NebulaConnection conn)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected I4, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			DysonSphere val = GameMain.data.dysonSpheres[packet.StarIndex];
			if (val == null)
			{
				return;
			}
			using (Multiplayer.Session.DysonSpheres.IncomingDysonSwarmPacket.On())
			{
				SwarmRemoveOrbitEvent @event = packet.Event;
				switch ((int)@event)
				{
				case 0:
					val.swarm.RemoveOrbit(packet.OrbitId);
					break;
				case 1:
				case 2:
					val.swarm.SetOrbitEnable(packet.OrbitId, (int)packet.Event == 2);
					break;
				case 3:
					val.swarm.RemoveSailsByOrbit(packet.OrbitId);
					break;
				default:
				{
					SwarmRemoveOrbitEvent event2 = packet.Event;
					throw new ArgumentOutOfRangeException("packet", "Unknown SwarmRemoveOrbitEvent type: " + ((object)(SwarmRemoveOrbitEvent)(ref event2)).ToString());
				}
				}
				DysonSphereManager.ClearSelection(packet.StarIndex, -1);
			}
			if (((BasePacketProcessor<DysonSwarmRemoveOrbitPacket>)this).IsHost)
			{
				Multiplayer.Session.DysonSpheres.SendPacketToDysonSphereExcept<DysonSwarmRemoveOrbitPacket>(packet, packet.StarIndex, (INebulaConnection)(object)conn);
			}
		}
	}
}
namespace NebulaNetwork.PacketProcessors.Trash
{
	[RegisterPacketProcessor]
	internal class TrashSystemClearAllTrashProcessor : PacketProcessor<TrashSystemClearAllTrashPacket>
	{
		protected override void ProcessPacket(TrashSystemClearAllTrashPacket packet, NebulaConnection conn)
		{
			if (((BasePacketProcessor<TrashSystemClearAllTrashPacket>)this).IsHost)
			{
				((INetworkProvider)base.Server).SendPacketExclude<TrashSystemClearAllTrashPacket>(packet, (INebulaConnection)(object)conn);
			}
			using (Multiplayer.Session.Trashes.IsIncomingRequest.On())
			{
				GameMain.data.trashSystem.ClearAllTrash();
			}
		}
	}
	[RegisterPacketProcessor]
	internal class TrashSystemLootFilterProcessor : PacketProcessor<TrashSystemLootFilterPacket>
	{
		protected override void ProcessPacket(TrashSystemLootFilterPacket packet, NebulaConnection conn)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if (((BasePacketProcessor<TrashSystemLootFilterPacket>)this).IsHost)
			{
				Multiplayer.Session.Network.SendPacketExclude<TrashSystemLootFilterPacket>(packet, (INebulaConnection)(object)conn);
			}
			Reader val = new Reader(packet.EnemyDropBansData);
			try
			{
				GameMain.data.trashSystem.enemyDropBans.Clear();
				int num = val.BinaryReader.ReadInt32();
				for (int i = 0; i < num; i++)
				{
					GameMain.data.trashSystem.enemyDropBans.Add(val.BinaryReader.ReadInt32());
				}
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}
	}
	[RegisterPacketProcessor]
	internal class TrashSystemNewPlanetTrashProcessor : PacketProcessor<TrashSystemNewPlanetTrashPacket>
	{
		protected override void ProcessPacket(TrashSystemNewPlanetTrashPacket packet, NebulaConnection conn)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			PlanetData val = GameMain.galaxy.PlanetById(packet.PlanetId);
			PlanetFactory val2 = val?.factory;
			if (val2 == null)
			{
				return;
			}
			if (((BasePacketProcessor<TrashSystemNewPlanetTrashPacket>)this).IsClient)
			{
				TrashManager.SetNextTrashId(packet.TrashId);
			}
			TrashSystem trashSystem = GameMain.data.trashSystem;
			VectorLF3 val3 = default(VectorLF3);
			((VectorLF3)(ref val3))..ctor(packet.Pos.x, packet.Pos.y, packet.Pos.z);
			val3 += ((VectorLF3)(ref val3)).normalized;
			VectorLF3 val4 = Maths.QRotateLF(val.runtimeRotation, val3);
			VectorLF3 normalized = ((VectorLF3)(ref val4)).normalized;
			VectorLF3 val5 = Maths.QRotateLF(val.runtimeRotation, val3) + val.uPosition;
			int astroId = val.star.astroId;
			double starGravity = trashSystem.GetStarGravity(val.star.id);
			TrashData val6 = default(TrashData);
			val6.landPlanetId = 0;
			val6.nearPlanetId = 0;
			val6.nearStarId = astroId;
			val6.nearStarGravity = starGravity;
			val6.life = packet.Life;
			val6.lPos = Vector3.zero;
			val6.lRot = Quaternion.identity;
			val6.uPos = val5 + RandomTable.SphericNormal(ref trashSystem.randSeed, 0.2);
			val4 = RandomTable.SphericNormal(ref trashSystem.randSeed, 1.0);
			val6.uRot = Quaternion.LookRotation(VectorLF3.op_Implicit(((VectorLF3)(ref val4)).normalized));
			val6.uVel = val.GetUniversalVelocityAtLocalPoint(GameMain.gameTime, VectorLF3.op_Implicit(val3)) + normalized * 10.0 + RandomTable.SphericNormal(ref trashSystem.randSeed, 3.0);
			val6.uAgl = VectorLF3.op_Implicit(RandomTable.SphericNormal(ref trashSystem.randSeed, 0.03));
			if (((BasePacketProcessor<TrashSystemNewPlanetTrashPacket>)this).IsClient)
			{
				val6.warningId = -1;
				TrashManager trashes = Multiplayer.Session.Trashes;
				int clientTrashCount = trashes.ClientTrashCount;
				trashes.ClientTrashCount = clientTrashCount + 1;
			}
			TrashObject val7 = default(TrashObject);
			((TrashObject)(ref val7))..ctor(packet.ItemId, packet.Count, packet.Inc, VectorLF3.op_Implicit(Maths.QInvRotateLF(trashSystem.gameData.relativeRot, val6.uPos - trashSystem.gameData.relativePos)), Quaternion.Inverse(trashSystem.gameData.relativeRot) * val6.uRot);
			using (Multiplayer.Session.Trashes.IsIncomingRequest.On())
			{
				int num = trashSystem.container.NewTrash(val7, val6);
				if (((BasePacketProcessor<TrashSystemNewPlanetTrashPacket>)this).IsHost)
				{
					packet.TrashId = num;
					((INetworkProvider)base.Server).SendPacketToPlanet<TrashSystemNewPlanetTrashPacket>(packet, packet.PlanetId);
				}
				else if (num != packet.TrashId)
				{
					Log.Warn($"TrashSystemNewPlanetTrashPacket mismatch: {packet.TrashId} => {num}");
				}
			}
		}
	}
	[RegisterPacketProcessor]
	internal class TrashSystemNewPlayerTrashProcessor : PacketProcessor<TrashSystemNewPlayerTrashPacket>
	{
		protected override void ProcessPacket(TrashSystemNewPlayerTrashPacket packet, NebulaConnection conn)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			Player val = GameMain.mainPlayer;
			if (packet.PlayerId != Multiplayer.Session.LocalPlayer.Id)
			{
				Dictionary<ushort, RemotePlayerModel> dictionary = default(Dictionary<ushort, RemotePlayerModel>);
				Locker remotePlayersModels = Multiplayer.Session.World.GetRemotePlayersModels(ref dictionary);
				try
				{
					if (!dictionary.TryGetValue(packet.PlayerId, out var value))
					{
						return;
					}
					val = value.PlayerInstance;
				}
				finally
				{
					((IDisposable)(Locker)(ref remotePlayersModels)).Dispose();
				}
			}
			if (((BasePacketProcessor<TrashSystemNewPlayerTrashPacket>)this).IsClient)
			{
				TrashManager.SetNextTrashId(packet.TrashId);
			}
			TrashSystem trashSystem = GameMain.data.trashSystem;
			VectorLF3 val2 = Maths.QRotateLF(val.uRotation, new VectorLF3(0f, 1f, 0f));
			VectorLF3 uPosition = val.uPosition;
			TrashObject val3 = default(TrashObject);
			((TrashObject)(ref val3))..ctor(packet.ItemId, packet.Count, packet.Inc, Vector3.zero, Quaternion.identity);
			TrashData val4 = default(TrashData);
			val4.landPlanetId = 0;
			val4.nearPlanetId = 0;
			val4.nearStarId = packet.NearStarId;
			StarData val5 = GameMain.galaxy.StarById(packet.NearStarId / 100);
			val4.nearStarGravity = ((val5 != null) ? trashSystem.GetStarGravity(packet.NearStarId / 100) : 0.0);
			val4.life = packet.Life;
			val4.lPos = Vector3.zero;
			val4.lRot = Quaternion.identity;
			val4.uPos = uPosition + RandomTable.SphericNormal(ref trashSystem.randSeed, 0.3);
			VectorLF3 val6 = RandomTable.SphericNormal(ref trashSystem.randSeed, 1.0);
			val4.uRot = Quaternion.LookRotation(VectorLF3.op_Implicit(((VectorLF3)(ref val6)).normalized), VectorLF3.op_Implicit(val2));
			val4.uVel = DataStructureExtensions.ToVectorLF3(packet.UVel);
			val4.uAgl = VectorLF3.op_Implicit(RandomTable.SphericNormal(ref trashSystem.randSeed, 0.03));
			GameScenarioLogic gameScenario = GameMain.gameScenario;
			if (gameScenario != null)
			{
				gameScenario.NotifyOnAddTrash(packet.ItemId, packet.Count);
			}
			if (((BasePacketProcessor<TrashSystemNewPlayerTrashPacket>)this).IsClient)
			{
				val4.warningId = -1;
				TrashManager trashes = Multiplayer.Session.Trashes;
				int clientTrashCount = trashes.ClientTrashCount;
				trashes.ClientTrashCount = clientTrashCount + 1;
			}
			using (Multiplayer.Session.Trashes.IsIncomingRequest.On())
			{
				int num = trashSystem.container.NewTrash(val3, val4);
				if (((BasePacketProcessor<TrashSystemNewPlayerTrashPacket>)this).IsHost)
				{
					packet.TrashId = num;
					((INetworkProvider)base.Server).SendPacket<TrashSystemNewPlayerTrashPacket>(packet);
				}
				else if (num != packet.TrashId)
				{
					Log.Warn($"TrashSystemNewPlayerTrashPacket mismatch: {packet.TrashId} => {num}");
				}
			}
		}
	}
	[RegisterPacketProcessor]
	internal class TrashSystemTrashRemovedProcessor : PacketProcessor<TrashSystemTrashRemovedPacket>
	{
		protected override void ProcessPacket(TrashSystemTrashRemovedPacket packet, NebulaConnection conn)
		{
			TrashObject[] trashObjPool = GameMain.data.trashSystem.container.trashObjPool;
			if (packet.TrashId < 0 || packet.TrashId >= trashObjPool.Length)
			{
				return;
			}
			ref TrashObject reference = ref trashObjPool[packet.TrashId];
			if (((BasePacketProcessor<TrashSystemTrashRemovedPacket>)this).IsHost)
			{
				if (reference.item != 0 || reference.count != 0)
				{
					GameMain.data.trashSystem.RemoveTrash(packet.TrashId);
				}
			}
			else if (reference.count != 0)
			{
				reference.item = packet.ItemId;
				using (Multiplayer.Session.Trashes.RemoveTrashFromOtherPlayers.On())
				{
					GameMain.data.trashSystem.RemoveTrash(packet.TrashId);
				}
				TrashManager trashes = Multiplayer.Session.Trashes;
				int clientTrashCount = trashes.ClientTrashCount;
				trashes.ClientTrashCount = clientTrashCount - 1;
				if (Multiplayer.Session.Trashes.ClientTrashCount <= 0)
				{
					Multiplayer.Session.Trashes.ClientTrashCount = 0;
				}
			}
		}
	}
}
namespace NebulaNetwork.PacketProcessors.Statistics
{
	[RegisterPacketProcessor]
	internal class MilestoneUnlockProcessor : PacketProcessor<MilestoneUnlockPacket>
	{
		protected override void ProcessPacket(MilestoneUnlockPacket packet, NebulaConnection conn)
		{
			bool flag = true;
			if (((BasePacketProcessor<MilestoneUnlockPacket>)this).IsHost)
			{
				INebulaPlayer val = base.Players.Get((INebulaConnection)(object)conn, (EConnectionStatus)3);
				if (val != null)
				{
					((INetworkProvider)base.Server).SendPacketExclude<MilestoneUnlockPacket>(packet, (INebulaConnection)(object)conn);
				}
				else
				{
					flag = false;
				}
			}
			if (!flag)
			{
				return;
			}
			using (Multiplayer.Session.Statistics.IsIncomingRequest.On())
			{
				if (GameMain.data.milestoneSystem.milestoneDatas.TryGetValue(packet.Id, out var value))
				{
					value.journalData.patternId = packet.PatternId;
					value.journalData.parameters = packet.Parameters;
					GameMain.data.milestoneSystem.UnlockMilestone(packet.Id, packet.UnlockTick);
				}
			}
		}
	}
	[RegisterPacketProcessor]
	internal class StatisticsDataProcessor : PacketProcessor<StatisticsDataPacket>
	{
		protected override void ProcessPacket(StatisticsDataPacket packet, NebulaConnection conn)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			Reader val = new Reader(packet.StatisticsBinaryData);
			try
			{
				Multiplayer.Session.Statistics.ImportAllData(val.BinaryReader);
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}
	}
	[RegisterPacketProcessor]
	internal class StatisticsRequestEventProcessor : PacketProcessor<StatisticsRequestEvent>
	{
		protected override void ProcessPacket(StatisticsRequestEvent packet, NebulaConnection conn)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (((BasePacketProcessor<StatisticsRequestEvent>)this).IsClient)
			{
				return;
			}
			INebulaPlayer val = base.Players.Get((INebulaConnection)(object)conn, (EConnectionStatus)3);
			if (val == null)
			{
				return;
			}
			StatisticEvent @event = packet.Event;
			if ((int)@event != 1)
			{
				if ((int)@event == 2)
				{
					Multiplayer.Session.Statistics.UnRegisterPlayer(val.Id);
					return;
				}
				StatisticEvent event2 = packet.Event;
				throw new ArgumentOutOfRangeException("packet", "Unknown event type: " + ((object)(StatisticEvent)(ref event2)).ToString());
			}
			Multiplayer.Session.Statistics.RegisterPlayer(conn, val.Id);
			Writer val2 = new Writer();
			try
			{
				Multiplayer.Session.Statistics.ExportAllData(val2.BinaryWriter);
				conn.SendPacket<StatisticsDataPacket>(new StatisticsDataPacket(val2.CloseAndGetBytes()));
			}
			finally
			{
				((IDisposable)val2)?.Dispose();
			}
		}
	}
	[RegisterPacketProcessor]
	internal class StatisticsUpdateProcessor : PacketProcessor<StatisticUpdateDataPacket>
	{
		protected override void ProcessPacket(StatisticUpdateDataPacket packet, NebulaConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			using (Multiplayer.Session.Statistics.IsIncomingRequest.On())
			{
				Reader val = new Reader(packet.StatisticsBinaryData);
				try
				{
					bool flag = false;
					ref FactoryProductionStat[] factoryStatPool = ref GameMain.statistics.production.factoryStatPool;
					int num = val.BinaryReader.ReadInt32();
					for (int i = 0; i < num; i++)
					{
						StatisticalSnapShot val2 = new StatisticalSnapShot(val.BinaryReader);
						for (int j = 0; j < val2.ProductionChangesPerFactory.Length; j++)
						{
							if (factoryStatPool[j] == null)
							{
								factoryStatPool[j] = new FactoryProductionStat();
								factoryStatPool[j].Init();
							}
							factoryStatPool[j].PrepareTick();
							for (int k = 0; k < val2.ProductionChangesPerFactory[j].Count; k++)
							{
								ProductionChangeStruct val3 = val2.ProductionChangesPerFactory[j][k];
								if (val3.IsProduction)
								{
									factoryStatPool[j].productRegister[val3.ProductId] += val3.Amount;
								}
								else
								{
									factoryStatPool[j].consumeRegister[val3.ProductId] += val3.Amount;
								}
							}
							factoryStatPool[j].powerGenRegister = val2.PowerGenerationRegister[j];
							factoryStatPool[j].powerConRegister = val2.PowerConsumptionRegister[j];
							factoryStatPool[j].powerChaRegister = val2.PowerChargingRegister[j];
							factoryStatPool[j].powerDisRegister = val2.PowerDischargingRegister[j];
							Multiplayer.Session.Statistics.PowerEnergyStoredData = val2.EnergyStored;
							factoryStatPool[j].hashRegister = val2.HashRegister[j];
							factoryStatPool[j].GameTick(val2.CapturedGameTick);
							flag |= factoryStatPool[j].itemChanged;
						}
					}
					if (flag)
					{
						UIRoot.instance.uiGame.statWindow.OnItemChange();
					}
				}
				finally
				{
					((IDisposable)val)?.Dispose();
				}
			}
		}
	}
}
namespace NebulaNetwork.PacketProcessors.Session
{
	[RegisterPacketProcessor]
	internal class GlobalGameDataRequestProcessor : PacketProcessor<GlobalGameDataRequest>
	{
		protected override void ProcessPacket(GlobalGameDataRequest packet, NebulaConnection conn)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			if (((BasePacketProcessor<GlobalGameDataRequest>)this).IsClient)
			{
				return;
			}
			Writer val = new Writer();
			try
			{
				GameMain.history.Export(val.BinaryWriter);
				conn.SendPacket<GlobalGameDataResponse>(new GlobalGameDataResponse((EDataType)1, val.CloseAndGetBytes()));
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
			Writer val2 = new Writer();
			try
			{
				CombatManager.SerializeOverwrite = true;
				GameMain.data.spaceSector.BeginSave();
				GameMain.data.spaceSector.Export(val2.BinaryWriter);
				GameMain.data.spaceSector.EndSave();
				CombatManager.SerializeOverwrite = false;
				conn.SendPacket<GlobalGameDataResponse>(new GlobalGameDataResponse((EDataType)2, val2.CloseAndGetBytes()));
			}
			finally
			{
				((IDisposable)val2)?.Dispose();
			}
			Writer val3 = new Writer();
			try
			{
				GameMain.data.milestoneSystem.Export(val3.BinaryWriter);
				conn.SendPacket<GlobalGameDataResponse>(new GlobalGameDataResponse((EDataType)3, val3.CloseAndGetBytes()));
			}
			finally
			{
				((IDisposable)val3)?.Dispose();
			}
			Writer val4 = new Writer();
			try
			{
				GameMain.data.trashSystem.Export(val4.BinaryWriter);
				conn.SendPacket<GlobalGameDataResponse>(new GlobalGameDataResponse((EDataType)4, val4.CloseAndGetBytes()));
			}
			finally
			{
				((IDisposable)val4)?.Dispose();
			}
			Writer val5 = new Writer();
			try
			{
				val5.BinaryWriter.Write(GameMain.sandboxToolsEnabled);
				conn.SendPacket<GlobalGameDataResponse>(new GlobalGameDataResponse((EDataType)5, val5.CloseAndGetBytes()));
			}
			finally
			{
				((IDisposable)val5)?.Dispose();
			}
		}
	}
	[RegisterPacketProcessor]
	internal class GlobalGameDataResponseProcessor : PacketProcessor<GlobalGameDataResponse>
	{
		protected override void ProcessPacket(GlobalGameDataResponse packet, NebulaConnection conn)
		{
			if (!((BasePacketProcessor<GlobalGameDataResponse>)this).IsHost)
			{
				GameStatesManager.ImportGlobalGameData(packet);
			}
		}
	}
	[RegisterPacketProcessor]
	public class HandshakeResponseProcessor : PacketProcessor<HandshakeResponse>
	{
		protected override void ProcessPacket(HandshakeResponse packet, NebulaConnection conn)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			Reader val = new Reader(packet.ModsSettings);
			try
			{
				for (int i = 0; i < packet.ModsSettingsCount; i++)
				{
					string key = val.BinaryReader.ReadString();
					PluginInfo val2 = Chainloader.PluginInfos[key];
					BaseUnityPlugin instance = val2.Instance;
					IMultiplayerModWithSettings val3 = (IMultiplayerModWithSettings)(object)((instance is IMultiplayerModWithSettings) ? instance : null);
					if (val3 != null)
					{
						val3.Import(val.BinaryReader);
					}
				}
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
			Config.Options.SyncSoil = packet.SyncSoil;
			((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = false;
			((LocalPlayer)Multiplayer.Session.LocalPlayer).SetPlayerData(packet.LocalPlayerData, packet.IsNewPlayer);
			Multiplayer.Session.IsInLobby = false;
			Multiplayer.ShouldReturnToJoinMenu = false;
			GameDesc val4 = new GameDesc();
			val4.SetForN

NebulaPatcher.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ABN;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Discord;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NGPT;
using NebulaAPI;
using NebulaAPI.DataStructures;
using NebulaAPI.GameState;
using NebulaAPI.Interfaces;
using NebulaAPI.Networking;
using NebulaModel;
using NebulaModel.Attributes;
using NebulaModel.DataStructures;
using NebulaModel.DataStructures.Chat;
using NebulaModel.Logger;
using NebulaModel.Networking;
using NebulaModel.Packets.Chat;
using NebulaModel.Packets.Combat;
using NebulaModel.Packets.Combat.DFHive;
using NebulaModel.Packets.Combat.DFRelay;
using NebulaModel.Packets.Combat.DFTinder;
using NebulaModel.Packets.Combat.GroundEnemy;
using NebulaModel.Packets.Combat.Mecha;
using NebulaModel.Packets.Combat.SpaceEnemy;
using NebulaModel.Packets.Factory;
using NebulaModel.Packets.Factory.Assembler;
using NebulaModel.Packets.Factory.BattleBase;
using NebulaModel.Packets.Factory.Belt;
using NebulaModel.Packets.Factory.Ejector;
using NebulaModel.Packets.Factory.Foundation;
using NebulaModel.Packets.Factory.Fractionator;
using NebulaModel.Packets.Factory.Inserter;
using NebulaModel.Packets.Factory.Laboratory;
using NebulaModel.Packets.Factory.Miner;
using NebulaModel.Packets.Factory.Monitor;
using NebulaModel.Packets.Factory.PowerExchanger;
using NebulaModel.Packets.Factory.PowerGenerator;
using NebulaModel.Packets.Factory.PowerTower;
using NebulaModel.Packets.Factory.RayReceiver;
using NebulaModel.Packets.Factory.Silo;
using NebulaModel.Packets.Factory.Splitter;
using NebulaModel.Packets.Factory.Storage;
using NebulaModel.Packets.Factory.Tank;
using NebulaModel.Packets.Factory.Turret;
using NebulaModel.Packets.GameHistory;
using NebulaModel.Packets.Logistics;
using NebulaModel.Packets.Planet;
using NebulaModel.Packets.Players;
using NebulaModel.Packets.Session;
using NebulaModel.Packets.Statistics;
using NebulaModel.Packets.Trash;
using NebulaModel.Packets.Universe;
using NebulaModel.Packets.Universe.Editor;
using NebulaModel.Packets.Warning;
using NebulaModel.Utils;
using NebulaNetwork;
using NebulaPatcher.Logger;
using NebulaPatcher.MonoBehaviours;
using NebulaPatcher.Patches.Dynamic;
using NebulaPatcher.Patches.Transpilers;
using NebulaWorld;
using NebulaWorld.Chat;
using NebulaWorld.Combat;
using NebulaWorld.Factory;
using NebulaWorld.GameStates;
using NebulaWorld.MonoBehaviours.Local.Chat;
using NebulaWorld.SocialIntegration;
using NebulaWorld.Universe;
using NebulaWorld.Warning;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("0.9.3.3")]
[assembly: AssemblyInformationalVersion("0.9.3.3+3bb1ae4")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("NebulaPatcher")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyProduct("NebulaPatcher")]
[assembly: AssemblyTitle("NebulaPatcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.9.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[GeneratedCode("Nerdbank.GitVersioning.Tasks", "3.6.133.12845")]
[ExcludeFromCodeCoverage]
internal static class ThisAssembly
{
	internal const string AssemblyConfiguration = "Release";

	internal const string AssemblyFileVersion = "0.9.3.3";

	internal const string AssemblyInformationalVersion = "0.9.3.3+3bb1ae4";

	internal const string AssemblyName = "NebulaPatcher";

	internal const string AssemblyTitle = "NebulaPatcher";

	internal const string AssemblyVersion = "0.9.3.0";

	internal static readonly DateTime GitCommitDate = new DateTime(638486122650000000L, DateTimeKind.Utc);

	internal const string GitCommitId = "3bb1ae4284b5f16508d9789eff7fcce645bb08ea";

	internal const bool IsPrerelease = false;

	internal const bool IsPublicRelease = true;

	internal const string RootNamespace = "NebulaPatcher";
}
namespace NebulaPatcher
{
	[BepInPlugin("dsp.nebula-multiplayer", "NebulaMultiplayerMod", "0.9.3.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class NebulaPlugin : BaseUnityPlugin, IMultiplayerMod
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ActivityJoinHandler <0>__ActivityManager_OnActivityJoin;
		}

		private static int command_ups;

		public string Version => Config.ModVersion;

		private void Awake()
		{
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			Log.Init((ILogger)(object)new BepInExLogger(((BaseUnityPlugin)this).Logger));
			Config.ModInfo = ((BaseUnityPlugin)this).Info;
			Config.LoadOptions();
			string[] commandLineArgs = Environment.GetCommandLineArgs();
			bool flag = false;
			string text = string.Empty;
			bool flag2 = false;
			bool flag3 = false;
			bool flag4 = false;
			for (int i = 0; i < commandLineArgs.Length; i++)
			{
				if (commandLineArgs[i] == "-server")
				{
					Multiplayer.IsDedicated = true;
					Log.Info(">> Initializing dedicated server");
				}
				if (commandLineArgs[i] == "-batchmode")
				{
					flag = true;
				}
				if (commandLineArgs[i] == "-newgame")
				{
					flag2 = true;
					if (i + 3 < commandLineArgs.Length)
					{
						int result2;
						float result3;
						if (!int.TryParse(commandLineArgs[i + 1], out var result))
						{
							Log.Warn(">> Can't set galaxy seed: " + commandLineArgs[i + 1] + " is not a integer");
						}
						else if (!int.TryParse(commandLineArgs[i + 2], out result2))
						{
							Log.Warn(">> Can't set star count: " + commandLineArgs[i + 2] + " is not a integer");
						}
						else if (!float.TryParse(commandLineArgs[i + 3], out result3))
						{
							Log.Warn(">> Can't set resource multiplier: " + commandLineArgs[i + 3] + " is not a floating point number");
						}
						else
						{
							Log.Info($">> Creating new game ({result}, {result2}, {result3:F1})");
							GameDesc val = new GameDesc();
							val.SetForNewGame(UniverseGen.algoVersion, result, result2, 1, result3);
							GameStatesManager.NewGameDesc = val;
							flag4 = true;
						}
					}
				}
				if (commandLineArgs[i] == "-newgame-cfg")
				{
					flag2 = true;
					GameDesc val2 = new GameDesc();
					DotNet35Random val3 = new DotNet35Random((int)(DateTime.UtcNow.Ticks / 10000));
					val2.SetForNewGame(UniverseGen.algoVersion, val3.Next(100000000), 64, 1, 1f);
					SetGameDescFromConfigFile(val2);
					Log.Info($">> Creating new game ({val2.galaxySeed}, {val2.starCount}, {val2.resourceMultiplier:F1})");
					GameStatesManager.NewGameDesc = val2;
					flag4 = true;
				}
				if (commandLineArgs[i] == "-load" && i + 1 < commandLineArgs.Length)
				{
					flag3 = true;
					text = commandLineArgs[i + 1];
					if (text.EndsWith(".dsv"))
					{
						text = text.Remove(text.Length - 4);
					}
					if (GameSave.SaveExist(text))
					{
						Log.Info(">> Loading save " + text);
						GameStatesManager.ImportedSaveName = text;
						flag4 = true;
					}
				}
				if (commandLineArgs[i] == "-load-latest")
				{
					flag3 = true;
					string[] files = Directory.GetFiles(GameConfig.gameSaveFolder, "*" + GameSave.saveExt, SearchOption.TopDirectoryOnly);
					long[] array = new long[files.Length];
					string[] array2 = new string[files.Length];
					for (int j = 0; j < files.Length; j++)
					{
						FileInfo fileInfo = new FileInfo(files[j]);
						array[j] = fileInfo.LastWriteTime.ToFileTime();
						array2[j] = fileInfo.Name.Substring(0, fileInfo.Name.Length - GameSave.saveExt.Length);
					}
					if (files.Length != 0)
					{
						Array.Sort(array, array2);
						text = array2[files.Length - 1];
						Log.Info(">> Loading save " + text);
						GameStatesManager.ImportedSaveName = text;
						flag4 = true;
					}
				}
				if (!(commandLineArgs[i] != "-ups") && i + 1 < commandLineArgs.Length)
				{
					if (int.TryParse(commandLineArgs[i + 1], out var result4))
					{
						Log.Info($">> Set UPS {result4}");
						command_ups = result4;
					}
					else
					{
						Log.Warn(">> Can't set UPS, " + commandLineArgs[i + 1] + " is not a valid number");
					}
				}
			}
			if (Multiplayer.IsDedicated && !flag4)
			{
				if (flag3)
				{
					Log.Error((text != string.Empty) ? (">> Can't find save with name " + text + "! Exiting...") : ">> Can't find any save in the folder! Exiting...");
				}
				else if (flag2)
				{
					Log.Error(">> New game parameters incorrect! Exiting...\nExpect: -newgame seed starCount resourceMltiplier");
				}
				else
				{
					Log.Error(">> -load or -newgame argument missing! Exiting...");
				}
				Application.Quit();
			}
			if (Multiplayer.IsDedicated && !flag)
			{
				Log.Warn("Dedicated server should be started with -batchmode argument");
			}
			try
			{
				Initialize();
			}
			catch (Exception ex)
			{
				Log.Error("Unhandled exception occurred while initializing Nebula:", ex);
			}
		}

		private void Update()
		{
			if (GameMain.isRunning && UIRoot.instance.launchSplash.willdone)
			{
				DiscordManager.Update();
			}
		}

		public bool CheckVersion(string hostVersion, string clientVersion)
		{
			return hostVersion.Equals(clientVersion);
		}

		private static void Initialize()
		{
			//IL_001a: 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_0025: Expected O, but got Unknown
			InitPatches();
			AddNebulaBootstrapper();
			object obj = <>O.<0>__ActivityManager_OnActivityJoin;
			if (obj == null)
			{
				ActivityJoinHandler val = ActivityManager_OnActivityJoin;
				<>O.<0>__ActivityManager_OnActivityJoin = val;
				obj = (object)val;
			}
			DiscordManager.Setup((ActivityJoinHandler)obj);
		}

		public static void StartDedicatedServer(string saveName)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			UIMainMenu_Patch.OnMultiplayerButtonClick();
			if (GameSave.SaveExist(saveName))
			{
				Log.Info("Starting dedicated server, loading save : " + saveName);
				DSPGame.StartGame(saveName);
				Log.Info($"Listening server on port {Config.Options.HostPort}");
				Multiplayer.HostGame((IServer)new Server(Config.Options.HostPort, true));
				if (command_ups != 0)
				{
					FPSController.SetFixUPS((double)command_ups);
				}
			}
		}

		public static void StartDedicatedServer(GameDesc gameDesc)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			UIMainMenu_Patch.OnMultiplayerButtonClick();
			if (gameDesc != null)
			{
				Log.Info("Starting dedicated server, create new game from parameters:");
				Log.Info($"seed={gameDesc.galaxySeed} starCount={gameDesc.starCount} resourceMultiplier={gameDesc.resourceMultiplier:F1}");
				DSPGame.StartGameSkipPrologue(gameDesc);
				Log.Info($"Listening server on port {Config.Options.HostPort}");
				Multiplayer.HostGame((IServer)new Server(Config.Options.HostPort, true));
				if (command_ups != 0)
				{
					FPSController.SetFixUPS((double)command_ups);
				}
			}
		}

		public static void SetGameDescFromConfigFile(GameDesc gameDesc)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "nebulaGameDescSettings.cfg"), true);
			int value = val.Bind<int>("Basic", "galaxySeed", -1, "Cluster Seed. Negative value: Random or remain the same.").Value;
			if (value >= 0)
			{
				gameDesc.galaxySeed = value;
			}
			int value2 = val.Bind<int>("Basic", "starCount", -1, "Number of Stars. Negative value: Default(64) or remain the same.").Value;
			if (value2 >= 0)
			{
				gameDesc.starCount = value2;
			}
			float value3 = val.Bind<float>("Basic", "resourceMultiplier", -1f, "Resource Multiplier. Infinte = 100. Negative value: Default(1.0f) or remain the same.").Value;
			if (value3 >= 0f)
			{
				gameDesc.resourceMultiplier = value3;
			}
			gameDesc.isPeaceMode = val.Bind<bool>("General", "isPeaceMode", false, "False: Enable enemy force (combat mode)").Value;
			gameDesc.isSandboxMode = val.Bind<bool>("General", "isSandboxMode", false, "True: Enable creative mode").Value;
			gameDesc.combatSettings.aggressiveness = val.Bind<float>("Combat", "aggressiveness", 1f, new ConfigDescription("Aggressiveness (Dummy = -1, Rampage = 3)", (AcceptableValueBase)(object)new AcceptableValueList<float>(new float[6] { -1f, 0f, 0.5f, 1f, 2f, 3f }), Array.Empty<object>())).Value;
			gameDesc.combatSettings.initialLevel = val.Bind<int>("Combat", "initialLevel", 0, new ConfigDescription("Initial Level (Original range: 0 to 10)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 30), Array.Empty<object>())).Value;
			gameDesc.combatSettings.initialGrowth = val.Bind<float>("Combat", "initialGrowth", 1f, "Initial Growth (Original range: 0 to 200%)").Value;
			gameDesc.combatSettings.initialColonize = val.Bind<float>("Combat", "initialColonize", 1f, "Initial Occupation (Original range: 1% to 200%").Value;
			gameDesc.combatSettings.maxDensity = val.Bind<float>("Combat", "maxDensity", 1f, "Max Density (Original range: 1 to 3)").Value;
			gameDesc.combatSettings.growthSpeedFactor = val.Bind<float>("Combat", "growthSpeedFactor", 1f, "Growth Speed (Original range: 25% to 300%)").Value;
			gameDesc.combatSettings.powerThreatFactor = val.Bind<float>("Combat", "powerThreatFactor", 1f, "Power Threat Factor (Original range: 1% to 1000%)").Value;
			gameDesc.combatSettings.battleThreatFactor = val.Bind<float>("Combat", "battleThreatFactor", 1f, "Combat Threat Factor (Original range: 1% to 1000%)").Value;
			gameDesc.combatSettings.battleExpFactor = val.Bind<float>("Combat", "battleExpFactor", 1f, "Combat XP Factor (Original range: 1% to 1000%)").Value;
		}

		private static async void ActivityManager_OnActivityJoin(string secret)
		{
			if (Multiplayer.IsActive)
			{
				Log.Warn("Cannot join lobby from Discord, we are already in a lobby.");
				return;
			}
			if (string.IsNullOrWhiteSpace(secret))
			{
				Log.Warn("Received Discord invite without IP address.");
				return;
			}
			string[] ipAddresses = CryptoUtils.FromBase64(secret).Split(new char[1] { ';' });
			if (ipAddresses.Length != 1 && ipAddresses.Length != 3)
			{
				Log.Warn("Received invalid discord invite.");
				return;
			}
			string ipAddress = string.Empty;
			if (ipAddresses.Length == 1 && ipAddresses[0].Contains("ngrok"))
			{
				ipAddress = ipAddresses[0];
			}
			bool flag = string.IsNullOrWhiteSpace(ipAddress);
			bool flag2 = flag;
			if (flag2)
			{
				flag2 = await IPUtils.IsIPv6Supported();
			}
			if (flag2 && ipAddresses.Length > 1 && IPUtils.IsIPv6(ipAddresses[1]))
			{
				ipAddress = ipAddresses[1] + ":" + ipAddresses[2];
			}
			if (string.IsNullOrWhiteSpace(ipAddress) && IPUtils.IsIPv4(ipAddresses[0]))
			{
				ipAddress = ipAddresses[0] + ":" + ipAddresses[2];
			}
			if (string.IsNullOrWhiteSpace(ipAddress))
			{
				Log.Warn("Received Discord invite with invalid IP address.");
				return;
			}
			Log.Info("Joining lobby from Discord...");
			UIMainMenu_Patch.OnMultiplayerButtonClick();
			UIMainMenu_Patch.JoinGame(ipAddress ?? "");
			DiscordManager.UpdateRichPresence(secret, (string)null, true, true);
		}

		private static void InitPatches()
		{
			Log.Info("Patching Dyson Sphere Program...");
			try
			{
				Log.Info("Applying patches from NebulaMultiplayerMod 0.9.3.0 made for game version 0.10.29.22015");
				Harmony val = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "dsp.nebula-multiplayer");
				if (Multiplayer.IsDedicated)
				{
					Log.Info("Patching for headless mode...");
					val.PatchAll(typeof(Dedicated_Server_Patch));
				}
				Log.Info("Patching completed successfully");
			}
			catch (Exception ex)
			{
				Log.Error("Unhandled exception occurred while patching the game:", ex);
				Harmony.CreateAndPatchAll(typeof(UIFatalErrorTip_Patch), (string)null);
				Log.Error("Nebula Multiplayer Mod is incompatible with game version, expected version 0.10.29.22015\nUnhandled exception occurred while patching the game.");
			}
		}

		private static void AddNebulaBootstrapper()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Log.Info("Applying Nebula behaviours..");
			GameObject val = new GameObject
			{
				name = "Nebula Multiplayer Mod"
			};
			val.AddComponent<NebulaBootstrapper>();
			Log.Info("Behaviours applied.");
		}
	}
	internal static class PluginInfo
	{
		public const string PLUGIN_NAME = "NebulaMultiplayerMod";

		public const string PLUGIN_SHORT_NAME = "Nebula";

		public const string PLUGIN_ID = "dsp.nebula-multiplayer";

		public const string PLUGIN_VERSION = "0.9.3.3";

		public const string PLUGIN_DISPLAY_VERSION = "0.9.3.0";
	}
	internal static class DSPGameVersion
	{
		public const string VERSION = "0.10.29.22015";
	}
}
namespace NebulaPatcher.Patches.Transpilers
{
	[HarmonyPatch(typeof(ACH_BroadcastStar))]
	internal class ACH_BroadcastStar_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("OnGameTick")]
		private static IEnumerable<CodeInstruction> OnGameTick_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			try
			{
				CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, il).MatchForward(false, (CodeMatch[])(object)new CodeMatch[5]
				{
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "gameData"), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "factories"), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsLdloc(i, (LocalBuilder)null)), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldelem_Ref, (object)null, (string)null)
				});
				CodeInstruction val2 = val.InstructionAt(3);
				CodeInstruction val3 = val.InstructionAt(7);
				Label label = default(Label);
				return val.CreateLabel(ref label).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { val2 })
					.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { val3 })
					.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<ACH_BroadcastStar, int, int, bool>>((Func<ACH_BroadcastStar, int, int, bool>)delegate(ACH_BroadcastStar instance, int factoryId, int generatorId)
					{
						if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost)
						{
							return true;
						}
						PlanetFactory obj2 = ((DeterminatorBase)instance).gameData.factories[factoryId];
						if (obj2 != null)
						{
							PowerSystem powerSystem = obj2.powerSystem;
							if (powerSystem != null)
							{
								_ = ref powerSystem.genPool[generatorId];
								if (true)
								{
									return ((DeterminatorBase)instance).gameData.factories[factoryId].index != -1;
								}
							}
						}
						return false;
					}) })
					.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
					{
						new CodeInstruction(OpCodes.Brtrue, (object)label)
					})
					.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
					{
						new CodeInstruction(OpCodes.Ret, (object)null)
					})
					.InstructionEnumeration();
			}
			catch
			{
				Log.Error("ACH_BroadcastStar.OnGameTick_Transpiler failed. Mod version not compatible with game version.");
				return array;
			}
		}
	}
	[HarmonyPatch(typeof(BattleBaseComponent))]
	internal class BattleBaseComponent_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("AutoPickTrash")]
		public static IEnumerable<CodeInstruction> BattleBaseComponent_AutoPickTrash_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator iLGenerator)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Expected O, but got Unknown
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Expected O, but got Unknown
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Expected O, but got Unknown
			try
			{
				Label label = default(Label);
				CodeMatcher val = new CodeMatcher(instructions, iLGenerator).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Ldarg_1, (object)null, (string)null)
				}).CreateLabel(ref label).Insert((CodeInstruction[])(object)new CodeInstruction[7]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredPropertyGetter(typeof(Multiplayer), "Session")),
					new CodeInstruction(OpCodes.Brfalse_S, (object)label),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredPropertyGetter(typeof(Multiplayer), "Session")),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredPropertyGetter(typeof(MultiplayerSession), "LocalPlayer")),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredPropertyGetter(typeof(ILocalPlayer), "IsClient")),
					new CodeInstruction(OpCodes.Brfalse_S, (object)label),
					new CodeInstruction(OpCodes.Ret, (object)null)
				});
				val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(TrashObject), "count"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Stloc_S, (object)null, (string)null)
				});
				CodeInstruction val2 = new CodeInstruction(OpCodes.Ldloc_S, val.InstructionAt(-3).operand);
				CodeInstruction val3 = new CodeInstruction(OpCodes.Ldloc_S, val.Operand);
				val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Bne_Un, (object)null, (string)null)
				}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[5]
				{
					new CodeInstruction(OpCodes.Ldarg_2, (object)null),
					val2,
					val3,
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(BattleBaseComponent_Transpiler), "AddPlayerSandCount", (Type[])null, (Type[])null)),
					new CodeInstruction(OpCodes.Ret, (object)null)
				});
				val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "AddItemFiltered"), (string)null)
				}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_1, (object)null)
				}).SetAndAdvance(OpCodes.Call, (object)AccessTools.Method(typeof(BattleBaseComponent_Transpiler), "AddItemFiltered", (Type[])null, (Type[])null));
				return val.InstructionEnumeration();
			}
			catch (Exception ex)
			{
				Log.Error("Transpiler BattleBaseComponent.AutoPickTrash failed.");
				Log.Error(ex);
				return instructions;
			}
		}

		private static void AddPlayerSandCount(TrashSystem trashSystem, int trashId, int sandCount)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			if (Multiplayer.IsActive && !Config.Options.SyncSoil)
			{
				IReadOnlyDictionary<INebulaConnection, INebulaPlayer> connected = Multiplayer.Session.Server.Players.Connected;
				int num = connected.Count + ((!Multiplayer.IsDedicated) ? 1 : 0);
				if (num > 0)
				{
					sandCount = (int)((float)sandCount / (float)num + 0.5f);
					PlayerSandCount val = new PlayerSandCount((long)sandCount, true);
					((INetworkProvider)Multiplayer.Session.Server).SendPacket<PlayerSandCount>(val);
				}
			}
			Player mainPlayer = GameMain.data.mainPlayer;
			lock (mainPlayer)
			{
				mainPlayer.SetSandCount(mainPlayer.sandCount + sandCount);
				mainPlayer.NotifySandCollectFromTrash(sandCount);
				trashSystem.RemoveTrash(trashId);
			}
		}

		private static int AddItemFiltered(StorageComponent storage, int itemId, int count, int inc, ref int remainInc, bool useBan, PlanetFactory factory)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			int num = storage.AddItemFiltered(itemId, count, inc, ref remainInc, useBan);
			if (!Multiplayer.IsActive)
			{
				return num;
			}
			if (num > 0)
			{
				int planetId = factory.planetId;
				int id = factory.planet.star.id;
				Multiplayer.Session.Network.SendPacketToStar<StorageSyncRealtimeChangePacket>(new StorageSyncRealtimeChangePacket(storage.id, (StorageSyncRealtimeChangeEvent)4, itemId, num, useBan, planetId), id);
			}
			return num;
		}
	}
	[HarmonyPatch(typeof(BuildTool_BlueprintPaste))]
	internal class BuildTool_BlueprintPaste_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("CreatePrebuilds")]
		private static IEnumerable<CodeInstruction> CreatePrebuilds_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Expected O, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, il).MatchForward(true, (CodeMatch[])(object)new CodeMatch[4]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsLdloc(i, (LocalBuilder)null)), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ceq, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Brfalse, (object)null, (string)null)
			});
			if (val.IsInvalid)
			{
				Log.Error("BuildTool_BlueprintPaste.CreatePrebuilds_Transpiler failed. Mod version not compatible with game version.");
				return array;
			}
			object operand = val.Instruction.operand;
			val = val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[4]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsLdloc(i, (LocalBuilder)null)), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "item"), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "ID"), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsStloc(i, (LocalBuilder)null)), (string)null)
			});
			if (!val.IsInvalid)
			{
				return val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<bool>>((Func<bool>)(() => Multiplayer.IsActive)) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Brtrue, operand)
				}).InstructionEnumeration();
			}
			Log.Error("BuildTool_BlueprintPaste.CreatePrebuilds_Transpiler 2 failed. Mod version not compatible with game version.");
			return array;
		}
	}
	[HarmonyPatch]
	internal class BuildTool_Click_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(BuildTool_Click), "CreatePrebuilds")]
		[HarmonyPatch(typeof(BuildTool_BlueprintPaste), "CreatePrebuilds")]
		private static IEnumerable<CodeInstruction> CreatePrebuilds_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator iL)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, iL).MatchForward(true, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldsfld && ((FieldInfo)i.operand).Name == "buildTargetAutoMove"), (string)null)
			});
			if (val.IsInvalid)
			{
				Log.Error("BuildTool_Click.CreatePrebuilds_Transpiler failed. Mod version not compatible with game version.");
				return array;
			}
			object operand = val.InstructionAt(1).operand;
			return val.Advance(2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<bool>>((Func<bool>)(() => Multiplayer.IsActive && Multiplayer.Session.Factories.IsIncomingRequest.Value && Multiplayer.Session.Factories.PacketAuthor != Multiplayer.Session.LocalPlayer.Id)) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Brtrue, operand)
			})
				.InstructionEnumeration();
		}
	}
	[HarmonyPatch]
	internal class BuildTool_Common_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(BuildTool_Click), "CreatePrebuilds")]
		[HarmonyPatch(typeof(BuildTool_Path), "CreatePrebuilds")]
		[HarmonyPatch(typeof(BuildTool_Inserter), "CreatePrebuilds")]
		[HarmonyPatch(typeof(BuildTool_Addon), "CreatePrebuilds")]
		private static IEnumerable<CodeInstruction> CreatePrebuilds_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsLdarg(i, (int?)null)), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "get_player"), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "get_inhandItemId"), (string)null)
			});
			if (val.IsInvalid)
			{
				Log.Error("BuildTool_Common.CreatePrebuilds_Transpiler failed. Mod version not compatible with game version.");
				return array;
			}
			CodeInstruction val2 = val.InstructionAt(11);
			return val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldc_I4_1, (object)null)
			}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { val2 }).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(BuildTool_Path))]
	internal class BuildTool_Path_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("CreatePrebuilds")]
		private static IEnumerable<CodeInstruction> CreatePrebuilds_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, il).MatchForward(false, (CodeMatch[])(object)new CodeMatch[5]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "get_controller"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldflda, (object)AccessTools.Field(typeof(PlayerController), "cmd"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(CommandState), "stage"), (string)null)
			});
			Label label = default(Label);
			if (!val.IsInvalid)
			{
				return val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<bool>>((Func<bool>)(() => Multiplayer.IsActive && Multiplayer.Session.Factories.IsIncomingRequest.Value && Multiplayer.Session.Factories.PacketAuthor != Multiplayer.Session.LocalPlayer.Id)) }).CreateLabelAt(val.Pos + 19 + 22, ref label).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Brtrue, (object)label)
				})
					.InstructionEnumeration();
			}
			Log.Error("BuildTool_Path.CreatePrebuilds_Transpiler failed. Mod version not compatible with game version.");
			return array;
		}
	}
	[HarmonyPatch(typeof(CargoTraffic))]
	internal class CargoTraffic_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("PickupBeltItems")]
		private static IEnumerable<CodeInstruction> PickupBeltItems_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator iL)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, iL).MatchForward(true, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "TryPickItem"), (string)null)
			});
			if (!val.IsInvalid)
			{
				return val.Advance(2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldloc_S, (object)5)
				}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldloc_3, (object)null)
				})
					.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
					{
						new CodeInstruction(OpCodes.Ldarg_2, (object)null)
					})
					.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
					{
						new CodeInstruction(OpCodes.Ldarg_3, (object)null)
					})
					.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action<int, int, int, bool>>((Action<int, int, int, bool>)delegate(int item, int cnt, int belt, bool all)
					{
						if (Multiplayer.IsActive && !all)
						{
							Multiplayer.Session.Belts.RegisterBeltPickupUpdate(item, cnt, belt);
						}
					}) })
					.InstructionEnumeration();
			}
			Log.Error("CargoTraffic.PickupBeltItems_Transpiler failed. Mod version not compatible with game version.");
			return array;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(CargoTraffic), "CreateRenderingBatches")]
		[HarmonyPatch(typeof(CargoTraffic), "AlterBeltConnections")]
		private static IEnumerable<CodeInstruction> IsPlanetPhysicsColliderDirty_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, il).MatchForward(false, (CodeMatch[])(object)new CodeMatch[5]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && i.operand?.ToString() == "PlanetData planet"), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && i.operand?.ToString() == "PlanetPhysics physics"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Stfld && i.operand?.ToString() == "System.Boolean isPlanetPhysicsColliderDirty"), (string)null)
			});
			if (!val.IsInvalid)
			{
				return val.Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
				{
					//IL_0055: Unknown result type (might be due to invalid IL or missing references)
					//IL_005b: Expected O, but got Unknown
					Label label = default(Label);
					matcher.CreateLabelAt(matcher.Pos + 5, ref label).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<bool>>((Func<bool>)(() => Multiplayer.IsActive && Multiplayer.Session.Factories.IsIncomingRequest.Value)) }).Insert((CodeInstruction[])(object)new CodeInstruction[1]
					{
						new CodeInstruction(OpCodes.Brtrue, (object)label)
					})
						.Advance(5);
				}, (Action<string>)null).InstructionEnumeration();
			}
			Log.Error("CargoTraffic_IsPlanetPhysicsColliderDirty_Transpiler failed. Mod version not compatible with game version.");
			return array;
		}
	}
	[HarmonyPatch(typeof(ConstructionModuleComponent))]
	internal class ConstructionModuleComponent_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPriority(600)]
		[HarmonyPatch("PlaceItems")]
		public static IEnumerable<CodeInstruction> PlaceItems_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: 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_0023: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			try
			{
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[10]
				{
					new CodeMatch((OpCode?)OpCodes.Ldarg_2, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.DeclaredPropertyGetter(typeof(Player), "package"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloca_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloca_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloca_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldc_I4_0, (object)null, (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "TakeTailItems"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(PrebuildData), "itemRequired"), (string)null)
				}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
				{
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					//IL_001c: Expected O, but got Unknown
					//IL_002f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0035: Expected O, but got Unknown
					//IL_0049: Unknown result type (might be due to invalid IL or missing references)
					//IL_004f: Expected O, but got Unknown
					//IL_006c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0072: Expected O, but got Unknown
					matcher.Advance(-2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[4]
					{
						new CodeInstruction(OpCodes.Ldarg_1, (object)null),
						new CodeInstruction(OpCodes.Ldloc_S, matcher.InstructionAt(1).operand),
						new CodeInstruction(OpCodes.Ldloc_S, matcher.InstructionAt(-4).operand),
						new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ConstructionModuleComponent_Transpiler), "SendPacket", (Type[])null, (Type[])null))
					});
				}, (Action<string>)null);
				return val.InstructionEnumeration();
			}
			catch (Exception ex)
			{
				Log.Error("Transpiler ConstructionModuleComponent.PlaceItems failed.");
				Log.Error(ex);
				return instructions;
			}
		}

		private static void SendPacket(PlanetFactory factory, ref PrebuildData prebuild, int itemCount)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			if (Multiplayer.IsActive)
			{
				PrebuildItemRequiredUpdate val = new PrebuildItemRequiredUpdate(factory.planetId, prebuild.id, itemCount);
				Multiplayer.Session.Network.SendPacketToLocalStar<PrebuildItemRequiredUpdate>(val);
			}
		}
	}
	[HarmonyPatch(typeof(ConstructionSystem))]
	internal class ConstructionSystem_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("AddBuildTargetToModules")]
		public static IEnumerable<CodeInstruction> AddBuildTargetToModules_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			try
			{
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[3]
				{
					new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Bgt_Un, (object)null, (string)null)
				});
				Log.Info((object)val.IsValid);
				object operand = val.InstructionAt(-2).operand;
				object operand2 = val.Operand;
				val.Advance(1).Insert((CodeInstruction[])(object)new CodeInstruction[4]
				{
					new CodeInstruction(OpCodes.Ldloc_S, operand),
					new CodeInstruction(OpCodes.Ldarg_2, (object)null),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ConstructionSystem_Transpiler), "IsClosestPlayer", (Type[])null, (Type[])null)),
					new CodeInstruction(OpCodes.Brfalse_S, operand2)
				});
				return val.InstructionEnumeration();
			}
			catch (Exception ex)
			{
				Log.Error("Transpiler ConstructionSystem.AddBuildTargetToModules failed.");
				Log.Error(ex);
				return instructions;
			}
		}

		private static bool IsClosestPlayer(float sqrDist, ref Vector3 pos)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (!Multiplayer.IsActive || sqrDist < 225f)
			{
				return true;
			}
			return sqrDist <= Multiplayer.Session.Drones.GetClosestRemotePlayerSqrDistance(pos);
		}
	}
	[HarmonyPatch(typeof(DFGReplicatorComponent))]
	internal class DFGReplicatorComponent_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("LogicTick")]
		public static IEnumerable<CodeInstruction> LogicTick_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: 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_0036: Expected O, but got Unknown
			try
			{
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "AddUnit"), (string)null)
				}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
				{
					//IL_0014: Unknown result type (might be due to invalid IL or missing references)
					//IL_001a: Expected O, but got Unknown
					//IL_0022: Unknown result type (might be due to invalid IL or missing references)
					//IL_0028: Expected O, but got Unknown
					//IL_0043: Unknown result type (might be due to invalid IL or missing references)
					//IL_0049: Expected O, but got Unknown
					//IL_0066: Unknown result type (might be due to invalid IL or missing references)
					//IL_006c: Expected O, but got Unknown
					matcher.RemoveInstruction().Insert((CodeInstruction[])(object)new CodeInstruction[4]
					{
						new CodeInstruction(OpCodes.Ldarg_1, (object)null),
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(DFGReplicatorComponent), "productFormId")),
						new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DFGReplicatorComponent_Transpiler), "AddUnit", (Type[])null, (Type[])null))
					});
				}, (Action<string>)null);
				return val.InstructionEnumeration();
			}
			catch (Exception ex)
			{
				Log.Error("Transpiler DFGReplicatorComponent.LogicTick failed.");
				Log.Error(ex);
				return instructions;
			}
		}

		private static int AddUnit(EnemyFormation enemyFormation, DFGBaseComponent gbase, int formId)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			if (!Multiplayer.IsActive)
			{
				return enemyFormation.AddUnit();
			}
			if (Multiplayer.Session.IsClient)
			{
				return 0;
			}
			int num = enemyFormation.AddUnit();
			if (num > 0)
			{
				DFGFormationAddUnitPacket val = new DFGFormationAddUnitPacket(gbase.groundSystem.planet.id, gbase.id, formId, num);
				((INetworkProvider)Multiplayer.Session.Server).SendPacketToStar<DFGFormationAddUnitPacket>(val, gbase.groundSystem.planet.star.id);
			}
			return 0;
		}
	}
	[HarmonyPatch(typeof(DFSReplicatorComponent))]
	internal class DFSReplicatorComponent_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("LogicTick")]
		public static IEnumerable<CodeInstruction> LogicTick_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: 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_0036: Expected O, but got Unknown
			try
			{
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "AddUnit"), (string)null)
				}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
				{
					//IL_0014: Unknown result type (might be due to invalid IL or missing references)
					//IL_001a: Expected O, but got Unknown
					//IL_0022: Unknown result type (might be due to invalid IL or missing references)
					//IL_0028: Expected O, but got Unknown
					//IL_0043: Unknown result type (might be due to invalid IL or missing references)
					//IL_0049: Expected O, but got Unknown
					//IL_0066: Unknown result type (might be due to invalid IL or missing references)
					//IL_006c: Expected O, but got Unknown
					matcher.RemoveInstruction().Insert((CodeInstruction[])(object)new CodeInstruction[4]
					{
						new CodeInstruction(OpCodes.Ldarg_1, (object)null),
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(DFSReplicatorComponent), "productFormId")),
						new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DFSReplicatorComponent_Transpiler), "AddUnit", (Type[])null, (Type[])null))
					});
				}, (Action<string>)null);
				return val.InstructionEnumeration();
			}
			catch (Exception ex)
			{
				Log.Error("Transpiler DFSReplicatorComponent.LogicTick failed.");
				Log.Error(ex);
				return instructions;
			}
		}

		private static int AddUnit(EnemyFormation enemyFormation, EnemyDFHiveSystem hive, int formId)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			if (!Multiplayer.IsActive)
			{
				return enemyFormation.AddUnit();
			}
			if (Multiplayer.Session.IsClient)
			{
				return 0;
			}
			int num = enemyFormation.AddUnit();
			if (num > 0)
			{
				DFSFormationAddUnitPacket val = new DFSFormationAddUnitPacket(hive.hiveAstroId, formId, num);
				((INetworkProvider)Multiplayer.Session.Server).SendPacket<DFSFormationAddUnitPacket>(val);
			}
			return 0;
		}
	}
	[HarmonyPatch(typeof(DispenserComponent))]
	public class DispenserComponent_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("InternalTick")]
		public static IEnumerable<CodeInstruction> InternalTick_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Expected O, but got Unknown
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Expected O, but got Unknown
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Expected O, but got Unknown
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Expected O, but got Unknown
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Expected O, but got Unknown
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Expected O, but got Unknown
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Expected O, but got Unknown
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Expected O, but got Unknown
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Expected O, but got Unknown
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Expected O, but got Unknown
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Expected O, but got Unknown
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Expected O, but got Unknown
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Expected O, but got Unknown
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Expected O, but got Unknown
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Expected O, but got Unknown
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Expected O, but got Unknown
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Expected O, but got Unknown
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Expected O, but got Unknown
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Expected O, but got Unknown
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[6]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_1, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsLdloc(i, (LocalBuilder)null)), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloca_S, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "PickFromStorage"), (string)null)
			}).RemoveInstruction().Insert((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DispenserComponent_Transpiler), "PickFromStorage", (Type[])null, (Type[])null))
			});
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[6]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "workCourierCount"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Stfld && ((FieldInfo)i.operand).Name == "workCourierCount"), (string)null)
			}).Insert((CodeInstruction[])(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DispenserComponent_Transpiler), "IdleCourierToWork", (Type[])null, (Type[])null))
			});
			val.Advance(8).MatchForward(false, (CodeMatch[])(object)new CodeMatch[6]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "workCourierCount"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Stfld && ((FieldInfo)i.operand).Name == "workCourierCount"), (string)null)
			}).Insert((CodeInstruction[])(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DispenserComponent_Transpiler), "IdleCourierToWork", (Type[])null, (Type[])null))
			});
			val.End().MatchBack(true, (CodeMatch[])(object)new CodeMatch[12]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_1, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsLdloc(i, (LocalBuilder)null)), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldelema, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloca_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "InsertIntoStorage"), (string)null)
			}).RemoveInstruction()
				.Insert((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DispenserComponent_Transpiler), "InsertIntoStorage", (Type[])null, (Type[])null))
				});
			return val.InstructionEnumeration();
		}

		public static int PickFromStorage(PlanetFactory factory, int entityId, int itemId, int count, out int inc)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			if (Multiplayer.IsActive)
			{
				Multiplayer.Session.Network.SendPacketToLocalStar<DispenserAddTakePacket>(new DispenserAddTakePacket(factory.planetId, entityId, (EDispenserAddTakeEvent)4, itemId, count, 0));
			}
			return factory.PickFromStorage(entityId, itemId, count, ref inc);
		}

		public static int InsertIntoStorage(PlanetFactory factory, int entityId, int itemId, int count, int inc, out int remainInc, bool useBan)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (Multiplayer.IsActive && !useBan)
			{
				Multiplayer.Session.Network.SendPacketToLocalStar<DispenserAddTakePacket>(new DispenserAddTakePacket(factory.planetId, entityId, (EDispenserAddTakeEvent)3, itemId, count, inc));
			}
			return factory.InsertIntoStorage(entityId, itemId, count, inc, ref remainInc, useBan);
		}

		public static void IdleCourierToWork(DispenserComponent dispenser)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			if (Multiplayer.IsActive)
			{
				Multiplayer.Session.Network.SendPacketToLocalPlanet<DispenserCourierPacket>(new DispenserCourierPacket(GameMain.mainPlayer.planetId, (int)Multiplayer.Session.LocalPlayer.Id, dispenser.id, dispenser.workCourierDatas[dispenser.workCourierCount].itemId, dispenser.workCourierDatas[dispenser.workCourierCount].itemCount));
			}
		}
	}
	[HarmonyPatch(typeof(EjectorComponent))]
	internal class EjectorComponent_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("InternalUpdate")]
		private static IEnumerable<CodeInstruction> InternalUpdate_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			try
			{
				CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(SailBullet), "lBegin"), (string)null)
				});
				CodeInstruction val2 = val.InstructionAt(-1);
				val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(DysonSwarm), "AddBullet", (Type[])null, (Type[])null), (string)null)
				}).Advance(2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[6]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(EjectorComponent), "planetId")),
					val2,
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(EjectorComponent), "orbitId")),
					Transpilers.EmitDelegate<Action<int, Vector3, int>>((Action<int, Vector3, int>)delegate(int planetId, Vector3 localPos, int orbitId)
					{
						//IL_0026: Unknown result type (might be due to invalid IL or missing references)
						//IL_003f: Unknown result type (might be due to invalid IL or missing references)
						//IL_0040: Unknown result type (might be due to invalid IL or missing references)
						//IL_0045: Unknown result type (might be due to invalid IL or missing references)
						//IL_0046: Unknown result type (might be due to invalid IL or missing references)
						//IL_0056: Unknown result type (might be due to invalid IL or missing references)
						if (Multiplayer.IsActive && Multiplayer.Session.Launch.Snapshots.ContainsKey(planetId / 100 - 1))
						{
							Projectile val3 = default(Projectile);
							val3.PlanetId = planetId;
							val3.TargetId = (ushort)orbitId;
							val3.LocalPos = localPos;
							Projectile item = val3;
							Multiplayer.Session.Launch.ProjectileBag.Add(item);
						}
					})
				});
				return val.InstructionEnumeration();
			}
			catch
			{
				Log.Error("EjectorComponent.InternalUpdate_Transpiler failed. Mod version not compatible with game version.");
				return array;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyDFGroundSystem))]
	internal class EnemyDFGroundSystem_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("GameTickLogic")]
		public static IEnumerable<CodeInstruction> GameTickLogic_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Expected O, but got Unknown
			try
			{
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[5]
				{
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.DeclaredPropertyGetter(typeof(EnemyDFGroundSystem), "isLocalLoaded"), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsStloc(i, (LocalBuilder)null)), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsLdloc(i, (LocalBuilder)null)), (string)null),
					new CodeMatch((OpCode?)OpCodes.Brfalse, (object)null, (string)null)
				});
				object operand = val.Instruction.operand;
				val.Advance(1).Insert((CodeInstruction[])(object)new CodeInstruction[2]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredPropertyGetter(typeof(Multiplayer), "IsActive")),
					new CodeInstruction(OpCodes.Brtrue_S, operand)
				});
				val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[5]
				{
					new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(EnemyUnitComponent), "behavior"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Stloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Switch, (object)null, (string)null)
				});
				object operand2 = val.Instruction.operand;
				val.Insert((CodeInstruction[])(object)new CodeInstruction[3]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Ldloc_S, operand2),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(EnemyDFGroundSystem_Transpiler), "SyncHatredTarget", (Type[])null, (Type[])null))
				});
				return val.InstructionEnumeration();
			}
			catch (Exception ex)
			{
				Log.Error("Transpiler EnemyDFGroundSystem.GameTickLogic failed. Ground DF untis aggro will not in sync.");
				Log.Error(ex);
				return instructions;
			}
		}

		private static void SyncHatredTarget(EnemyDFGroundSystem groundSystem, ref EnemyUnitComponent enemyUnit)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			if (!Multiplayer.IsActive)
			{
				return;
			}
			int id = groundSystem.planet.id;
			int[] array = Multiplayer.Session.Enemies.GroundTargets[id];
			int enemyId = enemyUnit.enemyId;
			if (enemyId >= array.Length)
			{
				return;
			}
			if (Multiplayer.Session.IsServer)
			{
				if ((int)((HatredTarget)(ref enemyUnit.hatred.max)).objectType == 6)
				{
					((HatredList)(ref enemyUnit.hatred)).ClearMax();
				}
				int target = enemyUnit.hatred.max.target;
				if (array[enemyId] != target)
				{
					array[enemyId] = target;
					int num = id / 100;
					DFGRetargetPacket val = new DFGRetargetPacket(id, enemyId, target);
					((INetworkProvider)Multiplayer.Session.Server).SendPacketToStar<DFGRetargetPacket>(val, num);
				}
			}
			else
			{
				enemyUnit.hatred.max.target = array[enemyId];
				enemyUnit.hatred.max.value = 100000;
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch("DeactivateUnit")]
		public static IEnumerable<CodeInstruction> DeactivateUnit_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			try
			{
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).End().MatchBack(true, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "RemoveEnemyFinal"), (string)null)
				}).Set(OpCodes.Call, (object)AccessTools.Method(typeof(EnemyDFGroundSystem_Transpiler), "RemoveEnemyFinal", (Type[])null, (Type[])null));
				return val.InstructionEnumeration();
			}
			catch (Exception ex)
			{
				Log.Error("Transpiler DeactivateUnit_Transpiler failed.");
				Log.Error(ex);
				return instructions;
			}
		}

		public static void RemoveEnemyFinal(PlanetFactory factory, int id)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			factory.RemoveEnemyFinal(id);
			if (Multiplayer.IsActive && Multiplayer.Session.IsServer)
			{
				int planetId = factory.planetId;
				int id2 = factory.planet.star.id;
				DFGDeactivateUnitPacket val = new DFGDeactivateUnitPacket(planetId, id);
				((INetworkProvider)Multiplayer.Session.Server).SendPacketToStar<DFGDeactivateUnitPacket>(val, id2);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyDFHiveSystem))]
	internal class EnemyDFHiveSystem_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("GameTickLogic")]
		public static IEnumerable<CodeInstruction> GameTickLogic_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			try
			{
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(DFRelayComponent), "RealizePlanetBase", (Type[])null, (Type[])null), (string)null)
				}).Set(OpCodes.Call, (object)AccessTools.Method(typeof(EnemyDFHiveSystem_Transpiler), "RealizePlanetBase", (Type[])null, (Type[])null));
				return val.InstructionEnumeration();
			}
			catch (Exception ex)
			{
				Log.Error("Transpiler EnemyDFHiveSystem.GameTickLogic failed.");
				Log.Error(ex);
				return instructions;
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch("KeyTickLogic")]
		public static IEnumerable<CodeInstruction> KeyTickLogic_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			try
			{
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(SpaceSector), "RemoveEnemyFinal", (Type[])null, (Type[])null), (string)null)
				}).Set(OpCodes.Call, (object)AccessTools.Method(typeof(EnemyDFHiveSystem_Transpiler), "RemoveEnemyFinal", (Type[])null, (Type[])null));
				return val.InstructionEnumeration();
			}
			catch (Exception ex)
			{
				Log.Error("Transpiler EnemyDFHiveSystem.KeyTickLogic failed.");
				Log.Error(ex);
				return instructions;
			}
		}

		private static void RealizePlanetBase(DFRelayComponent dFRelayComponent, SpaceSector spaceSector)
		{
			if (!Multiplayer.IsActive || Multiplayer.Session.IsServer)
			{
				dFRelayComponent.RealizePlanetBase(spaceSector);
			}
		}

		private static void RemoveEnemyFinal(SpaceSector spaceSector, int enemyId)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (enemyId <= 0)
			{
				return;
			}
			if (Multiplayer.IsActive)
			{
				if (!Multiplayer.Session.IsServer)
				{
					return;
				}
				Multiplayer.Session.Network.SendPacket<DFSRemoveEnemyDeferredPacket>(new DFSRemoveEnemyDeferredPacket(enemyId));
			}
			spaceSector.RemoveEnemyFinal(enemyId);
		}
	}
	[HarmonyPatch(typeof(GameMain))]
	internal class GameMain_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("FixedUpdate")]
		private static IEnumerable<CodeInstruction> FixedUpdate_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator iL)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, iL).MatchForward(true, (CodeMatch[])(object)new CodeMatch[4]
			{
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Player), "ApplyGamePauseState", (Type[])null, (Type[])null), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(GameMain), "_paused"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Brtrue, (object)null, (string)null)
			});
			if (val.IsInvalid)
			{
				Log.Error("GameMain.FixedUpdate_Transpiler failed. Mod version not compatible with game version.");
				return array;
			}
			object operand = val.Instruction.operand;
			Label label = default(Label);
			val.CreateLabelAt(val.Pos + 1, ref label).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[5]
			{
				new CodeInstruction(OpCodes.Brfalse_S, (object)label),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredPropertyGetter(typeof(Multiplayer), "Session")),
				new CodeInstruction(OpCodes.Brfalse_S, operand),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredPropertyGetter(typeof(Multiplayer), "Session")),
				new CodeInstruction(OpCodes.Callvirt, (object)AccessTools.DeclaredPropertyGetter(typeof(MultiplayerSession), "CanPause"))
			});
			return val.InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(LabComponent))]
	internal class LabComponent_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("InternalUpdateResearch")]
		private static IEnumerable<CodeInstruction> InternalUpdateResearch_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			try
			{
				CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[5]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsLdarg(i, (int?)null)), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(TechState), "hashUploaded"), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsLdarg(i, (int?)null)), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(TechState), "hashNeeded"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
				});
				object operand = val.Instruction.operand;
				val.Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<bool>>((Func<bool>)(() => !Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost)) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Brfalse_S, operand)
				});
				return val.InstructionEnumeration();
			}
			catch
			{
				Log.Error("LabComponent.InternalUpdateResearch_Transpiler failed. Mod version not compatible with game version.");
				return array;
			}
		}
	}
	[HarmonyPatch(typeof(LogisticShipRenderer))]
	public class LogisticShipRenderer_Transpiler
	{
		private delegate bool IsOutOfBounds(StationComponent[] stationComponent, int index);

		[HarmonyPatch("Update")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Update_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Expected O, but got Unknown
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Expected O, but got Unknown
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Expected O, but got Unknown
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Expected O, but got Unknown
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Expected O, but got Unknown
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Expected O, but got Unknown
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Expected O, but got Unknown
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Expected O, but got Unknown
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Expected O, but got Unknown
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Expected O, but got Unknown
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Expected O, but got Unknown
			Label label = default(Label);
			Label label2 = default(Label);
			CodeMatcher val = new CodeMatcher(instructions, il).MatchForward(false, (CodeMatch[])(object)new CodeMatch[6]
			{
				new CodeMatch((OpCode?)OpCodes.Stloc_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(LogisticShipRenderer), "transport"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(GalacticTransport), "stationCursor"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
			}).Advance(-3).CreateLabel(ref label)
				.Start()
				.MatchForward(false, (CodeMatch[])(object)new CodeMatch[4]
				{
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(LogisticShipRenderer), "transport"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(GalacticTransport), "stationPool"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(LogisticShipRenderer), "transport"))
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(GalacticTransport), "stationPool"))
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldloc_0, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<IsOutOfBounds>((IsOutOfBounds)delegate(StationComponent[] stationComponent, int index)
				{
					if (index >= stationComponent.Length && Multiplayer.IsActive && Multiplayer.Session.LocalPlayer.IsClient)
					{
						WarningManager.DisplayCriticalWarning("IndexOutOfBounds in LogisticShipRenderer. Consider reconnecting!");
					}
					return index < stationComponent.Length;
				}) })
				.Insert((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Brfalse, (object)label)
				})
				.MatchBack(false, (CodeMatch[])(object)new CodeMatch[4]
				{
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(LogisticShipRenderer), "transport"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(GalacticTransport), "stationPool"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null)
				})
				.CreateLabel(ref label2)
				.Start()
				.MatchForward(true, (CodeMatch[])(object)new CodeMatch[6]
				{
					new CodeMatch((OpCode?)OpCodes.Stloc_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(LogisticShipRenderer), "transport"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(GalacticTransport), "stationCursor"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
				})
				.SetOperandAndAdvance((object)label2);
			return val.InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(MechaLab))]
	public class MechaLab_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPatch("GameTick")]
		public static IEnumerable<CodeInstruction> GameTick_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[5]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Conv_I8, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "AddTechHash"), (string)null)
			});
			if (!val.IsInvalid)
			{
				return val.SetInstruction(Transpilers.EmitDelegate<Action<GameHistoryData, long>>((Action<GameHistoryData, long>)delegate(GameHistoryData history, long addcnt)
				{
					//IL_0031: Unknown result type (might be due to invalid IL or missing references)
					//IL_003b: Expected O, but got Unknown
					if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost)
					{
						history.AddTechHash(addcnt);
					}
					else
					{
						Multiplayer.Session.Network.SendPacket<GameHistoryResearchContributionPacket>(new GameHistoryResearchContributionPacket(addcnt, history.currentTech));
					}
				})).InstructionEnumeration();
			}
			Log.Error("MechaLab.GameTick_Transpiler failed. Mod version not compatible with game version.");
			return array;
		}
	}
	[HarmonyPatch(typeof(PlanetFactory))]
	internal class PlanetFactory_Transpiler
	{
		public delegate bool BoundsChecker(PlanetFactory factory, int index);

		private delegate bool CatchBeltFastFillIn(bool result, PlanetFactory factory, int beltId, int offset, int itemId, byte itemCount, byte itemInc);

		private delegate bool CatchBeltFastTakeOut(bool result, PlanetFactory factory, int beltId, int itemId, int count);

		public static readonly List<int> CheckPopupPresent = new List<int>();

		public static readonly Dictionary<int, List<int>> FaultyVeins = new Dictionary<int, List<int>>();

		private static void OnNewSetInserterPickTarget(int inserterId, int otherObjId, int offset, int objId, Vector3 pointPos)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			if (Multiplayer.IsActive)
			{
				IFactoryManager factories = Multiplayer.Session.Factories;
				if ((Multiplayer.Session.LocalPlayer.IsHost && !factories.IsIncomingRequest.Value) || Multiplayer.Session.LocalPlayer.Id == factories.PacketAuthor)
				{
					Multiplayer.Session.Network.SendPacketToLocalStar<NewSetInserterPickTargetPacket>(new NewSetInserterPickTargetPacket(objId, otherObjId, inserterId, offset, pointPos, GameMain.localPlanet?.id ?? (-1)));
				}
			}
		}

		private static void OnNewSetInserterInsertTarget(int inserterId, int otherObjId, int offset, int objId, Vector3 pointPos)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			if (Multiplayer.IsActive)
			{
				IFactoryManager factories = Multiplayer.Session.Factories;
				if ((Multiplayer.Session.LocalPlayer.IsHost && !factories.IsIncomingRequest.Value) || Multiplayer.Session.LocalPlayer.Id == factories.PacketAuthor)
				{
					Multiplayer.Session.Network.SendPacketToLocalStar<NewSetInserterInsertTargetPacket>(new NewSetInserterInsertTargetPacket(objId, otherObjId, inserterId, offset, pointPos, GameMain.localPlanet?.id ?? (-1)));
				}
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch("OnBeltBuilt")]
		private static IEnumerable<CodeInstruction> OnBeltBuilt_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator iLGenerator)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Expected O, but got Unknown
			CodeInstruction[] array = (instructions as CodeInstruction[]) ?? instructions.ToArray();
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)array, iLGenerator).MatchForward(true, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "SetInserterPickTarget"), (string)null)
			});
			if (val.IsInvalid)
			{
				Log.Error("PlanetFactory_Transpiler.OnBeltBuilt 1 failed. Mod version not compatible with game version.");
				return array;
			}
			List<CodeInstruction> list = val.InstructionsWithOffsets(-5, -1);
			CodeInstruction val2 = val.InstructionAt(-13);
			List<CodeInstruction> list2 = val.InstructionsWithOffsets(8, 10);
			val = val.Advance(1).InsertAndAdvance(li

NebulaWorld.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using Discord;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NebulaAPI;
using NebulaAPI.DataStructures;
using NebulaAPI.GameState;
using NebulaAPI.Interfaces;
using NebulaAPI.Networking;
using NebulaModel;
using NebulaModel.DataStructures;
using NebulaModel.DataStructures.Chat;
using NebulaModel.Logger;
using NebulaModel.Networking;
using NebulaModel.Networking.Serialization;
using NebulaModel.Packets.Chat;
using NebulaModel.Packets.Combat.DFHive;
using NebulaModel.Packets.Combat.GroundEnemy;
using NebulaModel.Packets.Combat.Mecha;
using NebulaModel.Packets.Factory;
using NebulaModel.Packets.Factory.Belt;
using NebulaModel.Packets.Factory.PowerTower;
using NebulaModel.Packets.Logistics;
using NebulaModel.Packets.Players;
using NebulaModel.Packets.Session;
using NebulaModel.Packets.Statistics;
using NebulaModel.Packets.Trash;
using NebulaModel.Packets.Universe;
using NebulaModel.Packets.Warning;
using NebulaModel.Utils;
using NebulaWorld.Chat;
using NebulaWorld.Chat.ChatLinks;
using NebulaWorld.Chat.Commands;
using NebulaWorld.Combat;
using NebulaWorld.Factory;
using NebulaWorld.GameDataHistory;
using NebulaWorld.GameStates;
using NebulaWorld.Logistics;
using NebulaWorld.MonoBehaviours;
using NebulaWorld.MonoBehaviours.Local;
using NebulaWorld.MonoBehaviours.Local.Chat;
using NebulaWorld.MonoBehaviours.Remote;
using NebulaWorld.Planet;
using NebulaWorld.Player;
using NebulaWorld.SocialIntegration;
using NebulaWorld.Statistics;
using NebulaWorld.Trash;
using NebulaWorld.Universe;
using NebulaWorld.Warning;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.TextCore;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("0.9.3.3")]
[assembly: AssemblyInformationalVersion("0.9.3.3+3bb1ae4")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("NebulaWorld")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyProduct("NebulaWorld")]
[assembly: AssemblyTitle("NebulaWorld")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.9.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[GeneratedCode("Nerdbank.GitVersioning.Tasks", "3.6.133.12845")]
[ExcludeFromCodeCoverage]
internal static class ThisAssembly
{
	internal const string AssemblyConfiguration = "Release";

	internal const string AssemblyFileVersion = "0.9.3.3";

	internal const string AssemblyInformationalVersion = "0.9.3.3+3bb1ae4";

	internal const string AssemblyName = "NebulaWorld";

	internal const string AssemblyTitle = "NebulaWorld";

	internal const string AssemblyVersion = "0.9.3.0";

	internal static readonly DateTime GitCommitDate = new DateTime(638486122650000000L, DateTimeKind.Utc);

	internal const string GitCommitId = "3bb1ae4284b5f16508d9789eff7fcce645bb08ea";

	internal const bool IsPrerelease = false;

	internal const bool IsPublicRelease = true;

	internal const string RootNamespace = "NebulaWorld";
}
namespace NebulaWorld
{
	public static class AssetLoader
	{
		private static AssetBundle assetBundle;

		public static AssetBundle AssetBundle
		{
			get
			{
				if ((Object)(object)assetBundle != (Object)null)
				{
					return assetBundle;
				}
				string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				if (directoryName == null)
				{
					Log.Warn("Plugin folder is null, unable to load chat");
					return null;
				}
				string text = Path.Combine(directoryName, "nebulabundle");
				assetBundle = AssetBundle.LoadFromFile(text);
				return assetBundle;
			}
		}
	}
	public static class InGamePopup
	{
		private static UIMessageBox displayedMessage;

		public static void FadeOut()
		{
			if (!((Object)(object)displayedMessage == (Object)null))
			{
				((UIDialog)displayedMessage).FadeOut();
				displayedMessage = null;
			}
		}

		public static void UpdateMessage(in string title, string message)
		{
			if (!((Object)(object)displayedMessage == (Object)null) && !(displayedMessage.m_TitleText.text != title))
			{
				displayedMessage.m_MessageText.horizontalOverflow = (HorizontalWrapMode)1;
				displayedMessage.m_MessageText.verticalOverflow = (VerticalWrapMode)1;
				displayedMessage.m_MessageText.text = message;
			}
		}

		public static void AskInput(string title, string message, ContentType inputType, string inputText, Action<string> onConfirm, Action onCancel)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_004a: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			displayedMessage = UIMessageBox.Show(title, message, Localization.Translate("取消"), Localization.Translate("确定"), 2, (Response)delegate
			{
				onCancel?.Invoke();
			}, (Response)delegate
			{
				onConfirm?.Invoke(GetInputField());
			});
			CreateInputField(inputType, inputText);
		}

		public static void ShowInfo(string title, string message, string btn1, Action resp1 = null)
		{
			Show(0, title, message, btn1, resp1);
		}

		public static void ShowInfo(string title, string message, string btn1, string btn2, Action resp1, Action resp2)
		{
			Show(0, title, message, btn1, btn2, resp1, resp2);
		}

		public static void ShowInfo(string title, string message, string btn1, string btn2, string btn3, Action resp1, Action resp2, Action resp3)
		{
			Show(0, title, message, btn1, btn2, btn3, resp1, resp2, resp3);
		}

		public static void ShowWarning(string title, string message, string btn1, Action resp1 = null)
		{
			Show(1, title, message, btn1, resp1);
		}

		public static void ShowWarning(string title, string message, string btn1, string btn2, Action resp1, Action resp2)
		{
			Show(1, title, message, btn1, btn2, resp1, resp2);
		}

		public static void ShowWarning(string title, string message, string btn1, string btn2, string btn3, Action resp1, Action resp2, Action resp3)
		{
			Show(1, title, message, btn1, btn2, btn3, resp1, resp2, resp3);
		}

		public static void ShowQuestion(string title, string message, string btn1, Action resp1 = null)
		{
			Show(2, title, message, btn1, resp1);
		}

		public static void ShowQuestion(string title, string message, string btn1, string btn2, Action resp1, Action resp2)
		{
			Show(2, title, message, btn1, btn2, resp1, resp2);
		}

		public static void ShowQuestion(string title, string message, string btn1, string btn2, string btn3, Action resp1, Action resp2, Action resp3)
		{
			Show(2, title, message, btn1, btn2, btn3, resp1, resp2, resp3);
		}

		public static void ShowError(string title, string message, string btn1, Action resp1 = null)
		{
			Show(3, title, message, btn1, resp1);
		}

		public static void ShowError(string title, string message, string btn1, string btn2, Action resp1, Action resp2)
		{
			Show(3, title, message, btn1, btn2, resp1, resp2);
		}

		public static void ShowError(string title, string message, string btn1, string btn2, string btn3, Action resp1, Action resp2, Action resp3)
		{
			Show(3, title, message, btn1, btn2, btn3, resp1, resp2, resp3);
		}

		private static void Show(int type, string title, string message, string btn1, Action resp1 = null)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			displayedMessage = UIMessageBox.Show(title, message, btn1, type, (Response)delegate
			{
				resp1?.Invoke();
			});
		}

		private static void Show(int type, string title, string message, string btn1, string btn2, Action resp1, Action resp2)
		{
			//IL_0023: 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_0039: Expected O, but got Unknown
			//IL_0039: Expected O, but got Unknown
			displayedMessage = UIMessageBox.Show(title, message, btn1, btn2, type, (Response)delegate
			{
				resp1?.Invoke();
			}, (Response)delegate
			{
				resp2?.Invoke();
			});
		}

		private static void Show(int type, string title, string message, string btn1, string btn2, string btn3, Action resp1, Action resp2, Action resp3)
		{
			//IL_002d: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_004f: Expected O, but got Unknown
			//IL_004f: Expected O, but got Unknown
			displayedMessage = UIMessageBox.Show(title, message, btn1, btn2, btn3, type, (Response)delegate
			{
				resp1?.Invoke();
			}, (Response)delegate
			{
				resp2?.Invoke();
			}, (Response)delegate
			{
				resp3?.Invoke();
			});
		}

		private static void CreateInputField(ContentType contentType, string text)
		{
			//IL_0046: 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)
			GameObject val = GameObject.Find("UI Root/Overlay Canvas/Nebula - Multiplayer Menu/Host IP Address/InputField");
			val = Object.Instantiate<GameObject>(val, ((Component)displayedMessage).transform.Find("Window/Body/Client"));
			((Object)val).name = "InputField";
			val.transform.localPosition = new Vector3(-150f, 0f, 0f);
			InputField component = val.GetComponent<InputField>();
			component.contentType = contentType;
			component.text = text;
		}

		private static string GetInputField()
		{
			return ((Component)((Component)displayedMessage).transform.Find("Window/Body/Client/InputField")).GetComponent<InputField>().text;
		}
	}
	public class LocalPlayer : ILocalPlayer, IDisposable
	{
		public bool IsInitialDataReceived { get; set; }

		public bool IsHost { get; set; }

		public bool IsClient => !IsHost;

		public bool IsNewPlayer { get; set; }

		public ushort Id => Data.PlayerId;

		public IPlayerData Data { get; set; }

		public void Dispose()
		{
			Data = null;
			GC.SuppressFinalize(this);
		}

		public void SetPlayerData(PlayerData data, bool isNewPlayer)
		{
			Data = (IPlayerData)(object)data;
			IsNewPlayer = isNewPlayer;
			if (!IsInitialDataReceived)
			{
				IsInitialDataReceived = true;
				if (Multiplayer.Session.IsGameLoaded)
				{
					Multiplayer.Session.World.SetupInitialPlayerState();
				}
			}
		}
	}
	public static class Multiplayer
	{
		public static MultiplayerSession Session { get; set; }

		public static bool IsActive => Session != null;

		public static bool IsLeavingGame { get; set; }

		public static bool ShouldReturnToJoinMenu { get; set; }

		public static bool IsInMultiplayerMenu { get; set; }

		public static bool IsDedicated { get; set; }

		public static void HostGame(IServer server)
		{
			IsLeavingGame = false;
			Session = new MultiplayerSession((INetworkProvider)(object)server);
			Session.Server.Start();
		}

		public static void JoinGame(IClient client)
		{
			IsLeavingGame = false;
			Session = new MultiplayerSession((INetworkProvider)(object)client);
			Session.Client.Start();
		}

		public static void LeaveGame()
		{
			IsLeavingGame = true;
			bool flag = Session?.IsGameLoaded ?? false;
			if (flag)
			{
				Session.World.HidePingIndicator();
			}
			Session?.Dispose();
			Session = null;
			if (flag)
			{
				if (!UIRoot.instance.backToMainMenu)
				{
					UIRoot.instance.backToMainMenu = true;
					DSPGame.EndGame();
				}
			}
			else if (ShouldReturnToJoinMenu)
			{
				GameObject val = GameObject.Find("Overlay Canvas");
				Transform val2 = val.transform.Find("Nebula - Multiplayer Menu");
				((Component)val2).gameObject.SetActive(true);
			}
			DiscordManager.UpdateRichPresence(string.Empty, DiscordManager.CreateSecret(), secretPassthrough: false, updateTimestamp: true);
		}
	}
	public class MultiplayerSession : IDisposable, IMultiplayerSession
	{
		private bool canPause = true;

		public DateTime StartTime;

		public SimulatedWorld World { get; set; }

		public CombatManager Combat { get; set; }

		public EnemyManager Enemies { get; set; }

		public StorageManager Storage { get; set; }

		public PowerTowerManager PowerTowers { get; set; }

		public BeltManager Belts { get; set; }

		public BuildToolManager BuildTools { get; set; }

		public DroneManager Drones { get; set; }

		public GizmoManager Gizmos { get; set; }

		public GameDataHistoryManager History { get; set; }

		private GameStatesManager State { get; set; }

		public CourierManager Couriers { get; set; }

		public ILSShipManager Ships { get; set; }

		public StationUIManager StationsUI { get; set; }

		public PlanetManager Planets { get; set; }

		public StatisticsManager Statistics { get; set; }

		public TrashManager Trashes { get; set; }

		public DysonSphereManager DysonSpheres { get; set; }

		public LaunchManager Launch { get; set; }

		public WarningManager Warning { get; set; }

		public bool IsInLobby { get; set; }

		public bool CanPause
		{
			get
			{
				return canPause;
			}
			set
			{
				canPause = value;
				SimulatedWorld.SetPauseIndicator(value);
			}
		}

		public ushort NumPlayers { get; set; } = 1;


		public INetworkProvider Network { get; set; }

		public IServer Server { get; set; }

		public IClient Client { get; set; }

		public ILocalPlayer LocalPlayer { get; set; }

		public IFactoryManager Factories { get; set; }

		public bool IsDedicated => Multiplayer.IsDedicated;

		public bool IsServer => Server != null;

		public bool IsClient => Client != null;

		public bool IsGameLoaded { get; set; }

		public MultiplayerSession(INetworkProvider networkProvider)
		{
			Network = networkProvider;
			IServer val = (IServer)(object)((networkProvider is IServer) ? networkProvider : null);
			if (val != null)
			{
				Server = val;
			}
			IClient val2 = (IClient)(object)((networkProvider is IClient) ? networkProvider : null);
			if (val2 != null)
			{
				Client = val2;
			}
			LocalPlayer = (ILocalPlayer)(object)new LocalPlayer();
			World = new SimulatedWorld();
			Combat = new CombatManager();
			Enemies = new EnemyManager();
			Factories = (IFactoryManager)(object)new FactoryManager();
			Storage = new StorageManager();
			PowerTowers = new PowerTowerManager();
			Belts = new BeltManager();
			BuildTools = new BuildToolManager();
			Drones = new DroneManager();
			Gizmos = new GizmoManager();
			History = new GameDataHistoryManager();
			State = new GameStatesManager();
			Couriers = new CourierManager();
			Ships = new ILSShipManager();
			StationsUI = new StationUIManager();
			Planets = new PlanetManager();
			Statistics = new StatisticsManager();
			Trashes = new TrashManager();
			DysonSpheres = new DysonSphereManager();
			Launch = new LaunchManager();
			Warning = new WarningManager();
			StartTime = DateTime.Now;
		}

		public void Dispose()
		{
			((IDisposable)Network)?.Dispose();
			Network = null;
			((IDisposable)LocalPlayer)?.Dispose();
			LocalPlayer = null;
			World?.Dispose();
			World = null;
			Combat?.Dispose();
			Combat = null;
			Enemies?.Dispose();
			Enemies = null;
			((IDisposable)Factories)?.Dispose();
			Factories = null;
			Storage?.Dispose();
			Storage = null;
			PowerTowers?.Dispose();
			PowerTowers = null;
			Belts?.Dispose();
			Belts = null;
			BuildTools?.Dispose();
			BuildTools = null;
			Drones?.Dispose();
			Drones = null;
			Gizmos?.Dispose();
			Gizmos = null;
			History?.Dispose();
			History = null;
			State?.Dispose();
			State = null;
			Couriers?.Dispose();
			Couriers = null;
			Ships = null;
			StationsUI?.Dispose();
			StationsUI = null;
			Planets?.Dispose();
			Planets = null;
			Statistics?.Dispose();
			Statistics = null;
			Trashes?.Dispose();
			Trashes = null;
			DysonSpheres?.Dispose();
			DysonSpheres = null;
			Launch?.Dispose();
			Launch = null;
			Warning?.Dispose();
			Warning = null;
			GC.SuppressFinalize(this);
		}

		public void OnGameLoadCompleted()
		{
			if (!IsGameLoaded)
			{
				Log.Info("Game load completed");
				IsGameLoaded = true;
				DiscordManager.UpdateRichPresence();
				if (Multiplayer.Session.LocalPlayer.IsHost)
				{
					GameMain.history.universeObserveLevel = SimulatedWorld.GetUniverseObserveLevel();
				}
				if (Multiplayer.Session.LocalPlayer.IsInitialDataReceived)
				{
					Multiplayer.Session.World.SetupInitialPlayerState();
				}
			}
		}
	}
	public class RemotePlayerModel
	{
		private const int PLAYER_PROTO_ID = 1;

		public string Username { get; set; }

		public ushort PlayerId { get; set; }

		public Transform PlayerTransform { get; set; }

		public Transform PlayerModelTransform { get; set; }

		public RemotePlayerMovement Movement { get; set; }

		public RemotePlayerAnimation Animator { get; set; }

		public TextMesh InGameNameText { get; set; }

		public Text StarmapNameText { get; set; }

		public Transform StarmapTracker { get; set; }

		public Player PlayerInstance { get; set; }

		public Mecha MechaInstance { get; set; }

		public RemotePlayerModel(ushort playerId, string username)
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected O, but got Unknown
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Expected O, but got Unknown
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Expected O, but got Unknown
			string prefabPath = ((ProtoSet<PlayerProto>)(object)LDB.players).Select(1).PrefabPath;
			if (prefabPath != null)
			{
				PlayerTransform = Object.Instantiate<Transform>(Resources.Load<Transform>(prefabPath));
				PlayerModelTransform = PlayerTransform.Find("Model");
				Object.Destroy((Object)(object)((Component)PlayerTransform).GetComponent<PlayerFootsteps>());
				Object.Destroy((Object)(object)((Component)PlayerTransform).GetComponent<PlayerEffect>());
				Object.Destroy((Object)(object)((Component)PlayerTransform).GetComponent<PlayerAudio>());
				((Component)PlayerTransform).GetComponent<Rigidbody>().isKinematic = true;
				Movement = ((Component)PlayerTransform).gameObject.AddComponent<RemotePlayerMovement>();
				((Component)PlayerTransform).gameObject.AddComponent<RemotePlayerEffects>();
				Animator = ((Component)PlayerTransform).gameObject.AddComponent<RemotePlayerAnimation>();
				Movement.Username = username;
				Movement.PlayerID = playerId;
				((Component)PlayerTransform).GetComponent<PlayerAnimator>().Start();
				((Behaviour)((Component)PlayerTransform).GetComponent<PlayerAnimator>()).enabled = false;
			}
			if ((Object)(object)PlayerTransform != (Object)null)
			{
				((Object)((Component)PlayerTransform).gameObject).name = $"Remote Player ({playerId})";
				PlayerInstance = new Player
				{
					transform = PlayerTransform
				};
			}
			if ((Object)(object)Animator != (Object)null)
			{
				Animator.PlayerAnimator.player = PlayerInstance;
			}
			MechaInstance = new Mecha();
			if (PlayerInstance != null)
			{
				PlayerInstance.mecha = MechaInstance;
				MechaInstance.Init(GameMain.data, PlayerInstance);
				MechaInstance.SetForNewGame();
				PlayerInstance.animator = Animator.PlayerAnimator;
				if ((Object)(object)PlayerModelTransform != (Object)null)
				{
					PlayerInstance.mechaArmorModel = ((Component)PlayerModelTransform).GetComponent<MechaArmorModel>();
					MechaArmorModel mechaArmorModel = PlayerInstance.mechaArmorModel;
					((ManualBehaviour)mechaArmorModel).data = PlayerInstance;
					mechaArmorModel.player = PlayerInstance;
					mechaArmorModel.mecha = MechaInstance;
					((ManualBehaviour)mechaArmorModel)._OnCreate();
					((ManualBehaviour)mechaArmorModel)._OnInit();
					for (int i = 0; i < PlayerModelTransform.childCount; i++)
					{
						((Component)PlayerModelTransform.GetChild(i)).gameObject.SetActive(true);
					}
				}
				PlayerInstance.controller = ((Component)PlayerTransform).gameObject.GetComponent<PlayerController>();
				PlayerController controller = PlayerInstance.controller;
				controller.gameData = GameMain.data;
				controller.player = PlayerInstance;
				controller.mecha = PlayerInstance.mecha;
				controller.model = PlayerModelTransform;
				((Behaviour)controller).enabled = false;
				controller.actionDeath = new PlayerAction_Death();
				((PlayerAction)controller.actionDeath).Init(PlayerInstance);
				PlayerInstance.isAlive = true;
				GameObject val = new GameObject("Camera Target");
				val.transform.SetParent(PlayerInstance.transform, false);
				PlayerInstance.cameraTarget = val.transform;
			}
			PlayerId = playerId;
			Username = username;
		}

		public void Destroy()
		{
			Object.Destroy((Object)(object)((Component)PlayerTransform).gameObject);
			PlayerTransform = null;
			PlayerModelTransform = null;
			Movement = null;
			Animator = null;
			PlayerInstance.Free();
			PlayerInstance = null;
			if ((Object)(object)StarmapTracker != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)StarmapTracker).gameObject);
			}
			if ((Object)(object)StarmapNameText != (Object)null)
			{
				Object.Destroy((Object)(object)StarmapNameText);
			}
			if ((Object)(object)InGameNameText != (Object)null)
			{
				Object.Destroy((Object)(object)InGameNameText);
			}
			StarmapTracker = null;
			StarmapNameText = null;
			InGameNameText = null;
		}
	}
	public static class SaveManager
	{
		private const string FILE_EXTENSION = ".server";

		private const ushort REVISION = 8;

		private static readonly Dictionary<string, IPlayerData> playerSaves = new Dictionary<string, IPlayerData>();

		public static IReadOnlyDictionary<string, IPlayerData> PlayerSaves => playerSaves;

		public static void SaveServerData(string saveName)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			string path = GameConfig.gameSaveFolder + saveName + ".server";
			NetDataWriter val = new NetDataWriter();
			val.Put("REV");
			val.Put((ushort)8);
			val.Put(playerSaves.Count + 1);
			foreach (KeyValuePair<string, IPlayerData> playerSafe in playerSaves)
			{
				string key = playerSafe.Key;
				val.Put(key);
				((INetSerializable)playerSafe.Value).Serialize((INetDataWriter)(object)val);
			}
			Log.Info(string.Format("Saving server data to {0}, Revision:{1} PlayerCount:{2}", saveName + ".server", (ushort)8, playerSaves.Count));
			val.Put(CryptoUtils.GetCurrentUserPublicKeyHash());
			((INetSerializable)Multiplayer.Session.LocalPlayer.Data).Serialize((INetDataWriter)(object)val);
			File.WriteAllBytes(path, val.Data);
			if (saveName == GameSave.AutoSaveTmp)
			{
				HandleAutoSave();
			}
		}

		private static void HandleAutoSave()
		{
			string text = GameConfig.gameSaveFolder + GameSave.AutoSaveTmp + ".server";
			string text2 = GameConfig.gameSaveFolder + GameSave.AutoSave0 + ".server";
			string text3 = GameConfig.gameSaveFolder + GameSave.AutoSave1 + ".server";
			string text4 = GameConfig.gameSaveFolder + GameSave.AutoSave2 + ".server";
			string text5 = GameConfig.gameSaveFolder + GameSave.AutoSave3 + ".server";
			if (File.Exists(text))
			{
				if (File.Exists(text5))
				{
					File.Delete(text5);
				}
				if (File.Exists(text4))
				{
					File.Move(text4, text5);
				}
				if (File.Exists(text3))
				{
					File.Move(text3, text4);
				}
				if (File.Exists(text2))
				{
					File.Move(text2, text3);
				}
				File.Move(text, text2);
			}
		}

		public static void LoadServerData(bool loadSaveFile)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			playerSaves.Clear();
			if (!loadSaveFile)
			{
				return;
			}
			string path = GameConfig.gameSaveFolder + DSPGame.LoadFile + ".server";
			if (!File.Exists(path))
			{
				Log.Info("No server file");
				return;
			}
			try
			{
				byte[] array = File.ReadAllBytes(path);
				NetDataReader val = new NetDataReader(array);
				string @string = val.GetString();
				if (@string != "REV")
				{
					throw new Exception("Incorrect header");
				}
				ushort uShort = val.GetUShort();
				Log.Info($"Loading server data revision {uShort} (Latest {(ushort)8})");
				if (uShort != 8 && ((uShort < 5 || uShort > 8) ? true : false))
				{
					throw new Exception($"Unsupported version {uShort}");
				}
				int @int = val.GetInt();
				for (int i = 0; i < @int; i++)
				{
					string string2 = val.GetString();
					PlayerData val2 = null;
					if (uShort >= 5)
					{
						if (uShort == 8)
						{
							val2 = val.Get<PlayerData>((Func<PlayerData>)(() => new PlayerData()));
						}
						else
						{
							val2 = new PlayerData();
							val2.Import((INetDataReader)(object)val, (int)uShort);
						}
					}
					if (!playerSaves.ContainsKey(string2) && val2 != null)
					{
						playerSaves.Add(string2, (IPlayerData)(object)val2);
					}
					else if (val2 == null)
					{
						Log.Warn($"Could not load player data from unsupported save file revision {uShort}");
					}
				}
			}
			catch (Exception ex)
			{
				playerSaves.Clear();
				Log.WarnInform("Skipping server data due to exception:\n" + ex.Message);
				Log.Warn((object)ex);
			}
		}

		public static bool TryAdd(string clientCertHash, IPlayerData playerData)
		{
			if (playerSaves.ContainsKey(clientCertHash))
			{
				return false;
			}
			playerSaves.Add(clientCertHash, playerData);
			return true;
		}

		public static bool TryRemove(string clientCertHash)
		{
			return playerSaves.Remove(clientCertHash);
		}
	}
	public class SimulatedWorld : IDisposable
	{
		private sealed class ThreadSafe
		{
			internal readonly Dictionary<ushort, RemotePlayerModel> RemotePlayersModels = new Dictionary<ushort, RemotePlayerModel>();
		}

		private readonly ThreadSafe threadSafe = new ThreadSafe();

		private LocalPlayerMovement localPlayerMovement;

		private Text pingIndicator;

		private bool IsPlayerJoining { get; set; }

		public void Dispose()
		{
			//IL_0003: 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)
			Dictionary<ushort, RemotePlayerModel> remotePlayersModels;
			Locker remotePlayersModels2 = GetRemotePlayersModels(out remotePlayersModels);
			try
			{
				foreach (RemotePlayerModel value in remotePlayersModels.Values)
				{
					value.Destroy();
				}
				remotePlayersModels.Clear();
			}
			finally
			{
				((IDisposable)(Locker)(ref remotePlayersModels2)).Dispose();
			}
			Object.Destroy((Object)(object)localPlayerMovement);
			SetPauseIndicator(canPause: true);
			GC.SuppressFinalize(this);
		}

		public Locker GetRemotePlayersModels(out Dictionary<ushort, RemotePlayerModel> remotePlayersModels)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return CollectionExtensions.GetLocked<Dictionary<ushort, RemotePlayerModel>>(threadSafe.RemotePlayersModels, ref remotePlayersModels);
		}

		public void SetupInitialPlayerState()
		{
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Invalid comparison between Unknown and I4
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Expected O, but got Unknown
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Expected O, but got Unknown
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Expected O, but got Unknown
			if (!Multiplayer.Session.IsGameLoaded)
			{
				Log.Warn("Trying to setup initial player state before the game is loaded!");
				return;
			}
			if (!Multiplayer.Session.LocalPlayer.IsInitialDataReceived)
			{
				Log.Warn("Trying to setup initial player state before the player data was received!");
				return;
			}
			LocalPlayer localPlayer = Multiplayer.Session.LocalPlayer as LocalPlayer;
			if (localPlayer != null && localPlayer.IsClient && !localPlayer.IsNewPlayer)
			{
				GameMain.mainPlayer.planetId = localPlayer.Data.LocalPlanetId;
				if (localPlayer.Data.LocalPlanetId == -1)
				{
					GameMain.mainPlayer.uPosition = new VectorLF3(localPlayer.Data.UPosition.x, localPlayer.Data.UPosition.y, localPlayer.Data.UPosition.z);
				}
				else
				{
					GameMain.mainPlayer.position = DataStructureExtensions.ToVector3(localPlayer.Data.LocalPlanetPosition);
					GameMain.mainPlayer.uPosition = new VectorLF3(GameMain.localPlanet.uPosition.x + (double)GameMain.mainPlayer.position.x, GameMain.localPlanet.uPosition.y + (double)GameMain.mainPlayer.position.y, GameMain.localPlanet.uPosition.z + (double)GameMain.mainPlayer.position.z);
				}
				GameMain.mainPlayer.uRotation = Quaternion.Euler(DataStructureExtensions.ToVector3(localPlayer.Data.Rotation));
				localPlayer.Data.Mecha.UpdateMech(GameMain.mainPlayer);
				GameMain.mainPlayer.mecha.forge.mecha = GameMain.mainPlayer.mecha;
				GameMain.mainPlayer.mecha.forge.player = GameMain.mainPlayer;
				GameMain.mainPlayer.mecha.forge.gameHistory = GameMain.data.history;
				GameMain.mainPlayer.mecha.forge.gameHistory = GameMain.data.history;
				GameMain.mainPlayer.mecha.groundCombatModule.AfterImport(GameMain.data);
				GameMain.mainPlayer.mecha.spaceCombatModule.AfterImport(GameMain.data);
				FixPlayerAfterImport();
			}
			Multiplayer.Session.Factories.InitializePrebuildRequests();
			if (localPlayer != null && localPlayer.IsClient)
			{
				((MechaData)localPlayer.Data.Mecha).TechBonuses.UpdateMech(GameMain.mainPlayer.mecha);
				Vector3 localPosition;
				if (localPlayer.IsNewPlayer)
				{
					GameMain.mainPlayer.mecha.coreEnergy = GameMain.mainPlayer.mecha.coreEnergyCap;
					GameMain.mainPlayer.mecha.energyShieldEnergy = GameMain.mainPlayer.mecha.energyShieldCapacity;
					GameMain.mainPlayer.mecha.hp = GameMain.mainPlayer.mecha.hpMaxApplied;
					if (GameMain.history.logisticShipWarpDrive)
					{
						GameMain.mainPlayer.TryAddItemToPackage(1210, 5, 0, false, 0, false);
					}
					localPosition = GameMain.mainPlayer.transform.localPosition;
					float magnitude = ((Vector3)(ref localPosition)).magnitude;
					if (magnitude > 0f)
					{
						Transform transform = GameMain.mainPlayer.transform;
						transform.localPosition *= (magnitude + 20f) / magnitude;
					}
				}
				else
				{
					PlanetData val = GameMain.galaxy.PlanetById(localPlayer.Data.LocalPlanetId);
					if (val != null)
					{
						localPosition = GameMain.mainPlayer.transform.localPosition;
						float num = ((Vector3)(ref localPosition)).magnitude - val.realRadius;
						if (num > 5f || (int)val.type == 5)
						{
							GameMain.mainPlayer.movementState = (EMovementState)2;
						}
					}
				}
				PlanetFactory factory = GameMain.mainPlayer.factory;
				if (factory != null)
				{
					factory.transport.RefreshDispenserTraffic(0);
				}
				DisplayPingIndicator();
				byte[] publicKey = CryptoUtils.GetPublicKey(CryptoUtils.GetOrCreateUserCert());
				Multiplayer.Session.Network.SendPacket<SyncComplete>(new SyncComplete(publicKey));
				Multiplayer.Session.Network.SendPacket<PlayerUpdateLocalStarId>(new PlayerUpdateLocalStarId(Multiplayer.Session.LocalPlayer.Id, GameMain.data.localStar?.id ?? (-1)));
				Multiplayer.Session.Network.SendPacket<WarningDataRequest>(new WarningDataRequest((WarningRequestEvent)0));
				InGamePopup.FadeOut();
			}
			if (Config.Options.SyncSoil && localPlayer != null)
			{
				localPlayer.Data.Mecha.SandCount = GameMain.mainPlayer.sandCount;
			}
			if (localPlayer != null)
			{
				GameMain.mainPlayer.mecha.appearance.overrideName = " " + localPlayer.Data.Username + " ";
			}
			localPlayerMovement = GameMain.mainPlayer.gameObject.AddComponentIfMissing<LocalPlayerMovement>();
			GameMain.mainPlayer.gameObject.AddComponentIfMissing<ChatManager>();
		}

		public static void FixPlayerAfterImport()
		{
			Player mainPlayer = GameMain.mainPlayer;
			int num = (mainPlayer.package.size - 1) / mainPlayer.GetPackageColumnCount() + 1;
			mainPlayer.package.SetSize(mainPlayer.packageColCount * num);
			mainPlayer.deliveryPackage.rowCount = num;
			mainPlayer.deliveryPackage.NotifySizeChange();
			ModuleFleet[] moduleFleets = mainPlayer.mecha.groundCombatModule.moduleFleets;
			for (int i = 0; i < moduleFleets.Length; i++)
			{
				((ModuleFleet)(ref moduleFleets[i])).ClearFleetForeignKey();
			}
			moduleFleets = mainPlayer.mecha.spaceCombatModule.moduleFleets;
			for (int j = 0; j < moduleFleets.Length; j++)
			{
				((ModuleFleet)(ref moduleFleets[j])).ClearFleetForeignKey();
			}
		}

		public void OnPlayerJoining(string username)
		{
			if (!IsPlayerJoining)
			{
				IsPlayerJoining = true;
				Multiplayer.Session.CanPause = true;
				GameMain.isFullscreenPaused = true;
				InGamePopup.ShowInfo(Localization.Translate("Loading"), string.Format(Localization.Translate("{0} joining the game, please wait\n(Use BulletTime mod to unfreeze the game)"), username), null);
			}
		}

		public static void OnPlayerJoinedGame(INebulaPlayer player)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			Multiplayer.Session.World.SpawnRemotePlayerModel(player.Data);
			GalaxyData galaxy = GameMain.galaxy;
			player.SendPacket<NameInputPacket>(new NameInputPacket(ref galaxy));
			if (Config.Options.SyncSoil)
			{
				Player mainPlayer = GameMain.mainPlayer;
				mainPlayer.sandCount += player.Data.Mecha.SandCount;
				Multiplayer.Session.Network.SendPacket<PlayerSandCount>(new PlayerSandCount(GameMain.mainPlayer.sandCount, false));
			}
			Multiplayer.Session.PowerTowers.ResetAndBroadcast();
			Writer val = new Writer();
			try
			{
				val.BinaryWriter.Write(GameMain.data.trashSystem.enemyDropBans.Count);
				foreach (int enemyDropBan in GameMain.data.trashSystem.enemyDropBans)
				{
					val.BinaryWriter.Write(enemyDropBan);
				}
				player.SendPacket<TrashSystemLootFilterPacket>(new TrashSystemLootFilterPacket(val.CloseAndGetBytes()));
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
			Log.Info($"Client{player.Data.PlayerId} - {player.Data.Username} joined");
			try
			{
				NebulaModAPI.OnPlayerJoinedGame?.Invoke(player.Data);
			}
			catch (Exception ex)
			{
				Log.Error("NebulaModAPI.OnPlayerJoinedGame error:\n" + ex);
			}
		}

		public static void OnPlayerLeftGame(INebulaPlayer player)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			Multiplayer.Session.World.DestroyRemotePlayerModel(player.Id);
			if (Config.Options.SyncSoil)
			{
				Player mainPlayer = GameMain.mainPlayer;
				mainPlayer.sandCount -= player.Data.Mecha.SandCount;
				UIRoot.instance.uiGame.OnSandCountChanged(GameMain.mainPlayer.sandCount, -player.Data.Mecha.SandCount);
				Multiplayer.Session.Network.SendPacket<PlayerSandCount>(new PlayerSandCount(GameMain.mainPlayer.sandCount, false));
			}
			Multiplayer.Session.PowerTowers.ResetAndBroadcast();
			Log.Info($"Client{player.Data.PlayerId} - {player.Data.Username} left");
			try
			{
				NebulaModAPI.OnPlayerLeftGame?.Invoke(player.Data);
			}
			catch (Exception ex)
			{
				Log.Error("NebulaModAPI.OnPlayerLeftGame error:\n" + ex);
			}
		}

		public void OnAllPlayersSyncCompleted()
		{
			IsPlayerJoining = false;
			InGamePopup.FadeOut();
			GameMain.isFullscreenPaused = false;
			Multiplayer.Session.CanPause = false;
		}

		public void SpawnRemotePlayerModel(IPlayerData playerData)
		{
			//IL_0003: 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)
			Dictionary<ushort, RemotePlayerModel> remotePlayersModels;
			Locker remotePlayersModels2 = GetRemotePlayersModels(out remotePlayersModels);
			try
			{
				if (!remotePlayersModels.ContainsKey(playerData.PlayerId))
				{
					Log.Info($"Spawn player model {playerData.PlayerId} {playerData.Username}");
					RemotePlayerModel remotePlayerModel = new RemotePlayerModel(playerData.PlayerId, playerData.Username);
					remotePlayerModel.Movement.LocalStarId = playerData.LocalStarId;
					remotePlayerModel.Movement.localPlanetId = playerData.LocalPlanetId;
					remotePlayersModels.Add(playerData.PlayerId, remotePlayerModel);
					PlanetData obj = GameMain.galaxy.PlanetById(playerData.LocalPlanetId);
					string arg = ((obj != null) ? obj.displayName : null) ?? "In space";
					string text = string.Format(Localization.Translate("[{0:HH:mm}] {1} connected ({2})"), DateTime.Now, playerData.Username, arg);
					ChatManager.Instance.SendChatMessage(text, (ChatMessageType)1);
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref remotePlayersModels2)).Dispose();
			}
		}

		public void DestroyRemotePlayerModel(ushort playerId)
		{
			//IL_0003: 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)
			Dictionary<ushort, RemotePlayerModel> remotePlayersModels;
			Locker remotePlayersModels2 = GetRemotePlayersModels(out remotePlayersModels);
			try
			{
				if (remotePlayersModels.TryGetValue(playerId, out var value))
				{
					string text = string.Format(Localization.Translate("[{0:HH:mm}] {1} disconnected"), DateTime.Now, value.Username);
					ChatManager.Instance.SendChatMessage(text, (ChatMessageType)1);
					value.Destroy();
					remotePlayersModels.Remove(playerId);
					if (remotePlayersModels.Count == 0 && Config.Options.AutoPauseEnabled)
					{
						Multiplayer.Session.CanPause = true;
					}
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref remotePlayersModels2)).Dispose();
			}
		}

		public void UpdateRemotePlayerRealtimeState(PlayerMovement packet)
		{
			//IL_0003: 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)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<ushort, RemotePlayerModel> remotePlayersModels;
			Locker remotePlayersModels2 = GetRemotePlayersModels(out remotePlayersModels);
			try
			{
				if (remotePlayersModels.TryGetValue(packet.PlayerId, out var value))
				{
					value.Movement.UpdatePosition(packet);
					value.Animator.UpdateState(packet);
					value.MechaInstance.energyShieldEnergyRate = (((packet.Flags & 8) != 0) ? 1 : 2);
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref remotePlayersModels2)).Dispose();
			}
		}

		public void RenderPlayerNameTagsOnStarmap(UIStarmap starmap)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: 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)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			Text playerNameText = starmap.playerNameText;
			Transform playerTrack = starmap.playerTrack;
			Dictionary<ushort, RemotePlayerModel> remotePlayersModels;
			Locker remotePlayersModels2 = GetRemotePlayersModels(out remotePlayersModels);
			try
			{
				Vector2 val9 = default(Vector2);
				foreach (RemotePlayerModel item in remotePlayersModels.Select((KeyValuePair<ushort, RemotePlayerModel> player) => player.Value))
				{
					Text val;
					Transform val2;
					if ((Object)(object)item.StarmapNameText != (Object)null && (Object)(object)item.StarmapTracker != (Object)null)
					{
						val = item.StarmapNameText;
						val2 = item.StarmapTracker;
					}
					else
					{
						Text val4 = (item.StarmapNameText = Object.Instantiate<Text>(playerNameText, ((Component)playerNameText).transform.parent));
						val = val4;
						val.text = item.Username ?? "";
						((Component)val).gameObject.SetActive(true);
						Transform val6 = (item.StarmapTracker = Object.Instantiate<Transform>(playerTrack, playerTrack.parent));
						val2 = val6;
						((Component)val2).gameObject.SetActive(true);
					}
					VectorLF3 uPosition;
					if (item.Movement.localPlanetId > 0)
					{
						PlanetData val7 = GameMain.galaxy.PlanetById(item.Movement.localPlanetId);
						uPosition = val7.uPosition;
						Vector3 val8 = DataStructureExtensions.ToVector3(item.Movement.GetLastPosition().LocalPlanetPosition);
						uPosition += VectorLF3.op_Implicit(Maths.QRotate(val7.runtimeRotation, val8));
					}
					else
					{
						uPosition = item.Movement.absolutePosition;
					}
					uPosition = (uPosition - starmap.viewTargetUPos) * 0.00025;
					if (starmap.WorldPointIntoScreen(VectorLF3.op_Implicit(uPosition), ref val9))
					{
						val2.position = VectorLF3.op_Implicit(uPosition);
						if (item.Movement.localPlanetId > 0)
						{
							PlanetData val10 = GameMain.galaxy.PlanetById(item.Movement.localPlanetId);
							Quaternion rotation = val10.runtimeRotation * Quaternion.LookRotation(item.PlayerModelTransform.forward, DataStructureExtensions.ToVector3(item.Movement.GetLastPosition().LocalPlanetPosition));
							val2.rotation = rotation;
						}
						else
						{
							Quaternion rotation2 = Quaternion.LookRotation(item.PlayerModelTransform.forward, item.PlayerTransform.localPosition);
							val2.rotation = rotation2;
						}
						Transform obj = val2;
						Vector3 localScale;
						if (!UIStarmap.isChangingToMilkyWay)
						{
							Vector3 one = Vector3.one;
							Vector3 val11 = ((Component)starmap.screenCamera).transform.position - val2.position;
							localScale = one * ((Vector3)(ref val11)).magnitude;
						}
						else
						{
							localScale = Vector3.zero;
						}
						obj.localScale = localScale;
						((Graphic)val).rectTransform.anchoredPosition = new Vector2(val9.x + (float)((val9.x > 600f) ? (-35) : 35), val9.y + (((double)val9.y > -350.0) ? (-19f) : 19f));
						((Component)val).gameObject.SetActive(!UIStarmap.isChangingToMilkyWay);
					}
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref remotePlayersModels2)).Dispose();
			}
		}

		public void ClearPlayerNameTagsOnStarmap()
		{
			//IL_0003: 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)
			Dictionary<ushort, RemotePlayerModel> remotePlayersModels;
			Locker remotePlayersModels2 = GetRemotePlayersModels(out remotePlayersModels);
			try
			{
				foreach (KeyValuePair<ushort, RemotePlayerModel> item in remotePlayersModels)
				{
					Object.Destroy((Object)(object)((Component)item.Value.StarmapNameText).gameObject);
					Object.Destroy((Object)(object)((Component)item.Value.StarmapTracker).gameObject);
					item.Value.StarmapNameText = null;
					item.Value.StarmapTracker = null;
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref remotePlayersModels2)).Dispose();
			}
		}

		public void RenderPlayerNameTagsInGame()
		{
			//IL_0003: 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)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<ushort, RemotePlayerModel> remotePlayersModels;
			Locker remotePlayersModels2 = GetRemotePlayersModels(out remotePlayersModels);
			try
			{
				foreach (RemotePlayerModel item in remotePlayersModels.Select((KeyValuePair<ushort, RemotePlayerModel> player) => player.Value))
				{
					TextMesh val;
					if ((Object)(object)item.InGameNameText != (Object)null)
					{
						val = item.InGameNameText;
					}
					else
					{
						TextMesh targetText = UIRoot.instance.uiGame.sailIndicator.targetText;
						GameObject val2 = new GameObject();
						val2.transform.SetParent(item.PlayerTransform, false);
						MeshRenderer val3 = val2.AddComponent<MeshRenderer>();
						((Renderer)val3).sharedMaterial = ((Renderer)((Component)targetText).gameObject.GetComponent<MeshRenderer>()).sharedMaterial;
						TextMesh val4 = val2.AddComponent<TextMesh>();
						val4.text = item.Username ?? "";
						val4.anchor = (TextAnchor)1;
						val4.font = targetText.font;
						val4.fontSize = 36;
						val = (item.InGameNameText = val4);
						((Component)val).gameObject.SetActive(true);
					}
					if (item.Movement.localPlanetId != Multiplayer.Session.LocalPlayer.Data.LocalPlanetId && item.Movement.localPlanetId <= 0)
					{
						((Component)val).gameObject.SetActive(false);
					}
					else if (!((Component)val).gameObject.activeSelf)
					{
						((Component)val).gameObject.SetActive(true);
					}
					Transform transform = ((Component)GameCamera.main).transform;
					((Component)val).transform.rotation = transform.rotation;
					float num = Vector3.Distance(((Component)val).transform.position, transform.position);
					float num2 = (float)Config.Options.NameTagSize / (GameCamera.instance.planetMode ? 10000f : 30000f);
					val.characterSize = num2 * Mathf.Clamp(num, 20f, 200f);
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref remotePlayersModels2)).Dispose();
			}
		}

		private void DisplayPingIndicator()
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find("Ping Indicator");
			if ((Object)(object)val == (Object)null)
			{
				GameObject val2 = GameObject.Find("label");
				pingIndicator = Object.Instantiate<GameObject>(val2, ((Component)UIRoot.instance.uiGame).gameObject.transform).GetComponent<Text>();
				((Object)((Component)pingIndicator).gameObject).name = "Ping Indicator";
				pingIndicator.alignment = (TextAnchor)0;
				((Behaviour)pingIndicator).enabled = true;
				RectTransform component = ((Component)pingIndicator).GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0f, 1f);
				component.offsetMax = new Vector2(-68f, -40f);
				component.offsetMin = new Vector2(10f, -100f);
				pingIndicator.text = "";
				pingIndicator.fontSize = 14;
			}
			else
			{
				pingIndicator = val.GetComponent<Text>();
				((Behaviour)pingIndicator).enabled = true;
			}
		}

		public void HidePingIndicator()
		{
			if ((Object)(object)pingIndicator != (Object)null)
			{
				((Behaviour)pingIndicator).enabled = false;
			}
		}

		public void UpdatePingIndicator(string text)
		{
			if ((Object)(object)pingIndicator != (Object)null)
			{
				pingIndicator.text = text;
			}
		}

		public static void SetPauseIndicator(bool canPause)
		{
			GameObject val = GameObject.Find("UI Root/Overlay Canvas/In Game/Esc Menu/pause-text");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Text component = val.GetComponent<Text>();
			Localizer component2 = val.GetComponent<Localizer>();
			if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2))
			{
				if (!canPause)
				{
					component.text = Localization.Translate("--  Nebula Multiplayer  --");
					component2.stringKey = Localization.Translate("--  Nebula Multiplayer  --");
				}
				else
				{
					component.text = Localization.Translate("游戏已暂停");
					component2.stringKey = Localization.Translate("游戏已暂停");
				}
			}
		}

		public static int GetUniverseObserveLevel()
		{
			int result = 0;
			for (int num = 4104; num >= 4101; num--)
			{
				if (GameMain.history.TechUnlocked(num))
				{
					result = num % 10;
					break;
				}
			}
			return result;
		}
	}
}
namespace NebulaWorld.Warning
{
	public class WarningManager : IDisposable
	{
		public readonly ToggleSwitch IsIncomingMonitorPacket = new ToggleSwitch();

		private int idleCycle;

		private ConcurrentBag<NebulaConnection> requesters = new ConcurrentBag<NebulaConnection>();

		private WarningDataPacket warningDataPacket = new WarningDataPacket();

		private WarningSignalPacket warningSignalPacket;

		private WarningSystem ws;

		public int TickSignal { get; set; }

		public int TickData { get; set; }

		public long LastRequestTime { get; set; }

		public void Dispose()
		{
			requesters = null;
			warningSignalPacket = null;
			warningDataPacket = null;
			GC.SuppressFinalize(this);
		}

		public void HandleRequest(WarningDataRequest packet, NebulaConnection conn)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)packet.Event == 0)
			{
				conn.SendPacket<WarningSignalPacket>(warningSignalPacket);
			}
			else if (warningSignalPacket.Tick == warningDataPacket.Tick)
			{
				conn.SendPacket<WarningDataPacket>(warningDataPacket);
			}
			else
			{
				requesters.Add(conn);
			}
		}

		public void SendBroadcastIfNeeded()
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			ws = GameMain.data.warningSystem;
			if (CheckAndUpdateSignal())
			{
				warningSignalPacket.Tick = (int)GameMain.gameTick;
				Multiplayer.Session.Network.SendPacket<WarningSignalPacket>(warningSignalPacket);
				idleCycle = 0;
			}
			else if (++idleCycle > 60)
			{
				warningSignalPacket.Tick = (int)GameMain.gameTick;
				Multiplayer.Session.Network.SendPacket<WarningSignalPacket>(warningSignalPacket);
				idleCycle = 0;
			}
			if (!requesters.IsEmpty)
			{
				Writer val = new Writer();
				try
				{
					warningDataPacket.ActiveWarningCount = ExportBinaryData(val.BinaryWriter);
					warningDataPacket.BinaryData = val.CloseAndGetBytes();
					warningDataPacket.Tick = warningSignalPacket.Tick;
				}
				finally
				{
					((IDisposable)val)?.Dispose();
				}
				NebulaConnection result;
				while (requesters.TryTake(out result))
				{
					result.SendPacket<WarningDataPacket>(warningDataPacket);
				}
			}
		}

		private bool CheckAndUpdateSignal()
		{
			bool flag = warningSignalPacket.SignalCount != ws.warningSignalCount;
			warningSignalPacket.SignalCount = ws.warningSignalCount;
			if (flag)
			{
				warningSignalPacket.SignalCount = ws.warningSignalCount;
				warningSignalPacket.Signals = new int[warningSignalPacket.SignalCount];
				warningSignalPacket.Counts = new int[warningSignalPacket.SignalCount];
			}
			for (int i = 0; i < ws.warningSignalCount; i++)
			{
				int num = ws.warningSignals[i];
				if (warningSignalPacket.Signals[i] != num || warningSignalPacket.Counts[i] != ws.warningCounts[num])
				{
					warningSignalPacket.Signals[i] = num;
					warningSignalPacket.Counts[i] = ws.warningCounts[num];
					flag = true;
				}
			}
			return flag;
		}

		private int ExportBinaryData(BinaryWriter bw)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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)
			//IL_0057: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			WarningData[] warningPool = ws.warningPool;
			for (int i = 1; i < ws.warningCursor; i++)
			{
				WarningData val = warningPool[i];
				if (val.id == i && val.state > 0)
				{
					bw.Write(val.signalId);
					bw.Write(val.detailId);
					bw.Write(val.astroId);
					bw.Write(val.localPos.x);
					bw.Write(val.localPos.y);
					bw.Write(val.localPos.z);
					int value = ((val.factoryId == -3) ? val.objectId : (-1));
					bw.Write(value);
					num++;
				}
			}
			return num;
		}

		public void ImportBinaryData(BinaryReader br, int activeWarningCount)
		{
			ws = GameMain.data.warningSystem;
			int num = ws.warningCapacity;
			while (activeWarningCount + 1 > num)
			{
				num *= 2;
			}
			if (num > ws.warningCapacity)
			{
				ws.SetWarningCapacity(num);
			}
			ws.warningCursor = activeWarningCount + 1;
			WarningData[] warningPool = GameMain.data.warningSystem.warningPool;
			TrashContainer container = GameMain.data.trashSystem.container;
			for (int i = 1; i <= activeWarningCount; i++)
			{
				warningPool[i].id = i;
				warningPool[i].state = 1;
				warningPool[i].signalId = br.ReadInt32();
				warningPool[i].detailId = br.ReadInt32();
				warningPool[i].astroId = br.ReadInt32();
				warningPool[i].localPos.x = br.ReadSingle();
				warningPool[i].localPos.y = br.ReadSingle();
				warningPool[i].localPos.z = br.ReadSingle();
				int num2 = br.ReadInt32();
				if (num2 >= 0 && num2 < container.trashCursor && container.trashObjPool[num2].item > 0)
				{
					container.trashDataPool[num2].warningId = i;
				}
			}
		}

		public static void DisplayTemporaryWarning(string warningText, int millisecond)
		{
			DisplayCriticalWarning(warningText);
			ThreadingHelper.Instance.StartAsyncInvoke((Func<Action>)delegate
			{
				Thread.Sleep(millisecond);
				return RemoveCriticalWarning;
			});
		}

		public static void DisplayCriticalWarning(string warningText)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			WarningSystem warningSystem = GameMain.data.warningSystem;
			if (warningSystem.criticalWarnings.TryGetValue((ECriticalWarning)0, out var value))
			{
				if (value.warningParam != 0)
				{
					value.warningParam = 0;
					value.Update();
					warningSystem.UpdateCriticalWarningText();
				}
			}
			else
			{
				CriticalWarningData value2 = new CriticalWarningData((ECriticalWarning)0, 0)
				{
					warningText = warningText
				};
				warningSystem.criticalWarnings.Add((ECriticalWarning)0, value2);
				warningSystem.UpdateCriticalWarningText();
			}
		}

		private static void RemoveCriticalWarning()
		{
			GameMain.data.warningSystem.UnsetCriticalWarning((ECriticalWarning)0);
		}

		public WarningManager()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			WarningSignalPacket val = new WarningSignalPacket();
			val.Signals = new int[8];
			val.Counts = new int[8];
			warningSignalPacket = val;
			base..ctor();
		}
	}
}
namespace NebulaWorld.Universe
{
	public class DysonSphereManager : IDisposable
	{
		private sealed class ThreadSafe
		{
			internal readonly Dictionary<int, List<INebulaConnection>> Subscribers = new Dictionary<int, List<INebulaConnection>>();
		}

		public readonly ToggleSwitch IncomingDysonSwarmPacket = new ToggleSwitch();

		public readonly ToggleSwitch IsIncomingRequest = new ToggleSwitch();

		private readonly List<DysonSphereStatusPacket> statusPackets = new List<DysonSphereStatusPacket>();

		private readonly ThreadSafe threadSafe = new ThreadSafe();

		public bool IsNormal { get; set; } = true;


		public bool InBlueprint { get; set; }

		public int RequestingIndex { get; set; } = -1;


		public void Dispose()
		{
			GC.SuppressFinalize(this);
		}

		private Locker GetSubscribers(out Dictionary<int, List<INebulaConnection>> subscribers)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return CollectionExtensions.GetLocked<Dictionary<int, List<INebulaConnection>>>(threadSafe.Subscribers, ref subscribers);
		}

		public void SendPacketToDysonSphere<T>(T packet, int starIndex) where T : class, new()
		{
			//IL_0003: 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)
			Dictionary<int, List<INebulaConnection>> subscribers;
			Locker subscribers2 = GetSubscribers(out subscribers);
			try
			{
				if (!subscribers.TryGetValue(starIndex, out var value))
				{
					return;
				}
				foreach (INebulaConnection item in value)
				{
					item.SendPacket<T>(packet);
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref subscribers2)).Dispose();
			}
		}

		public void SendPacketToDysonSphereExcept<T>(T packet, int starIndex, INebulaConnection exception) where T : class, new()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, List<INebulaConnection>> subscribers;
			Locker subscribers2 = GetSubscribers(out subscribers);
			try
			{
				if (!subscribers.TryGetValue(starIndex, out var value))
				{
					return;
				}
				foreach (INebulaConnection item in value.Where((INebulaConnection conn) => !((IEquatable<INebulaConnection>)conn).Equals(exception)))
				{
					item.SendPacket<T>(packet);
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref subscribers2)).Dispose();
			}
		}

		public void RegisterPlayer(INebulaConnection conn, int starIndex)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			Dictionary<int, List<INebulaConnection>> subscribers;
			Locker subscribers2 = GetSubscribers(out subscribers);
			try
			{
				if (!subscribers.TryGetValue(starIndex, out var value))
				{
					value = new List<INebulaConnection>();
					subscribers.Add(starIndex, value);
					statusPackets.Add(new DysonSphereStatusPacket(GameMain.data.dysonSpheres[starIndex]));
					Multiplayer.Session.Launch.Register(starIndex);
				}
				if (!value.Contains(conn))
				{
					value.Add(conn);
					conn.SendPacket<DysonSphereStatusPacket>(statusPackets.Find((DysonSphereStatusPacket x) => x.StarIndex == starIndex));
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref subscribers2)).Dispose();
			}
		}

		public void UnRegisterPlayer(INebulaConnection conn, int starIndex)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, List<INebulaConnection>> subscribers;
			Locker subscribers2 = GetSubscribers(out subscribers);
			try
			{
				if (!subscribers.TryGetValue(starIndex, out var value))
				{
					return;
				}
				value.Remove(conn);
				if (value.Count == 0)
				{
					subscribers.Remove(starIndex);
					statusPackets.Remove(statusPackets.Find((DysonSphereStatusPacket x) => x.StarIndex == starIndex));
					Multiplayer.Session.Launch.Unregister(starIndex);
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref subscribers2)).Dispose();
			}
		}

		public void UnRegisterPlayer(INebulaConnection conn)
		{
			//IL_0003: 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)
			Dictionary<int, List<INebulaConnection>> subscribers;
			Locker subscribers2 = GetSubscribers(out subscribers);
			try
			{
				List<int> list = new List<int>();
				foreach (KeyValuePair<int, List<INebulaConnection>> item in subscribers)
				{
					item.Value.Remove(conn);
					if (item.Value.Count == 0)
					{
						list.Add(item.Key);
					}
				}
				foreach (int starIndex in list)
				{
					subscribers.Remove(starIndex);
					statusPackets.Remove(statusPackets.Find((DysonSphereStatusPacket x) => x.StarIndex == starIndex));
					Multiplayer.Session.Launch.Unregister(starIndex);
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref subscribers2)).Dispose();
			}
		}

		public void UpdateSphereStatusIfNeeded()
		{
			foreach (DysonSphereStatusPacket statusPacket in statusPackets)
			{
				DysonSphere val = GameMain.data.dysonSpheres[statusPacket.StarIndex];
				if (!((double)Math.Abs(statusPacket.GrossRadius - val.grossRadius) < 1E-09) || statusPacket.EnergyReqCurrentTick != val.energyReqCurrentTick || statusPacket.EnergyGenCurrentTick != val.energyGenCurrentTick)
				{
					statusPacket.GrossRadius = val.grossRadius;
					statusPacket.EnergyReqCurrentTick = val.energyReqCurrentTick;
					statusPacket.EnergyGenCurrentTick = val.energyGenCurrentTick;
					this.SendPacketToDysonSphere<DysonSphereStatusPacket>(statusPacket, statusPacket.StarIndex);
				}
			}
		}

		public void RequestDysonSphere(int starIndex, bool showInfo = true)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			StarData val = GameMain.galaxy.stars[starIndex];
			RequestingIndex = starIndex;
			Log.Info($"Requesting DysonSphere for system {val.displayName} (Index: {val.index})");
			Multiplayer.Session.Network.SendPacket<DysonSphereLoadRequest>(new DysonSphereLoadRequest(val.index, (DysonSphereRequestEvent)2));
			ClearSelection(starIndex);
			if (showInfo)
			{
				InGamePopup.ShowInfo(Localization.Translate("Loading"), string.Format(Localization.Translate("Loading Dyson sphere {0}, please wait"), val.displayName), null);
			}
		}

		public void UnloadRemoteDysonSpheres()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			int num = GameMain.localStar?.index ?? UIRoot.instance.uiGame.dysonEditor.selection.viewStar?.index ?? (-1);
			for (int i = 0; i < GameMain.data.dysonSpheres.Length; i++)
			{
				if (GameMain.data.dysonSpheres[i] != null && i != num)
				{
					Log.Info($"Unload DysonSphere at system {GameMain.galaxy.stars[i].displayName} (Index: {i})");
					Multiplayer.Session.Network.SendPacket<DysonSphereLoadRequest>(new DysonSphereLoadRequest(i, (DysonSphereRequestEvent)3));
					GameMain.data.dysonSpheres[i] = null;
				}
			}
			IsNormal = true;
		}

		public void HandleDesync(int starIndex, INebulaConnection conn)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			if (Multiplayer.Session.LocalPlayer.IsHost)
			{
				conn.SendPacket<DysonSphereData>(new DysonSphereData(starIndex, Array.Empty<byte>(), (DysonSphereRespondEvent)3));
			}
			else if (IsNormal)
			{
				IsNormal = false;
				InGamePopup.ShowWarning(Localization.Translate("Desync"), string.Format(Localization.Translate("Dyson sphere id[{0}] {1} is desynced."), starIndex, GameMain.galaxy.stars[starIndex].displayName), Localization.Translate("Reload"), delegate
				{
					RequestDysonSphere(starIndex);
				});
			}
		}

		public static int QueryOrbitId(DysonSwarm swarm)
		{
			int result = ((swarm.orbitCursor <= 20) ? swarm.orbitCursor : (-1));
			for (int i = 1; i < swarm.orbitCursor; i++)
			{
				if (swarm.orbits[i].id == 0)
				{
					result = i;
					break;
				}
			}
			return result;
		}

		public static void ClearSelection(int starIndex, int layerId = -1)
		{
			DESelection selection = UIRoot.instance.uiGame.dysonEditor.selection;
			if (selection.viewStar != null && selection.viewStar.index == starIndex)
			{
				if (layerId == -1)
				{
					selection.ClearAllSelection();
				}
				else if (selection.IsLayerSelected(layerId))
				{
					selection.ClearComponentSelection();
				}
			}
		}
	}
	public class LaunchManager
	{
		private HashSet<int> planetIds = new HashSet<int>();

		public ConcurrentBag<Projectile> ProjectileBag { get; set; } = new ConcurrentBag<Projectile>();


		public ConcurrentDictionary<int, DysonLaunchData> Snapshots { get; set; } = new ConcurrentDictionary<int, DysonLaunchData>();


		public void Dispose()
		{
			ProjectileBag = null;
			Snapshots = null;
			planetIds = null;
		}

		public void Register(int starIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if (Snapshots.IsEmpty)
			{
				Projectile result;
				while (ProjectileBag.TryTake(out result))
				{
				}
			}
			Snapshots.TryAdd(starIndex, new DysonLaunchData(starIndex));
		}

		public void Unregister(int starIndex)
		{
			Snapshots.TryRemove(starIndex, out var _);
		}

		public void CollectProjectile()
		{
			//IL_001d: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (Snapshots.IsEmpty)
			{
				return;
			}
			Projectile result;
			while (ProjectileBag.TryTake(out result))
			{
				int key = result.PlanetId / 100 - 1;
				if (Snapshots.TryGetValue(key, out var value))
				{
					if (result.TargetId <= 40)
					{
						result.Interval = value.BulletTick;
						value.BulletList.Add(result);
						value.BulletTick = 0;
					}
					else
					{
						result.Interval = value.RocketTick;
						value.RocketList.Add(result);
						value.RocketTick = 0;
					}
				}
			}
			foreach (DysonLaunchData value2 in Snapshots.Values)
			{
				byte bulletTick = value2.BulletTick;
				value2.BulletTick = (byte)(bulletTick + 1);
				bulletTick = value2.RocketTick;
				value2.RocketTick = (byte)(bulletTick + 1);
			}
		}

		public void SendBroadcastIfNeeded()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			if (Snapshots.IsEmpty)
			{
				return;
			}
			foreach (DysonLaunchData value in Snapshots.Values)
			{
				if (value.BulletList.Count > 0 || value.RocketList.Count > 0)
				{
					Multiplayer.Session.DysonSpheres.SendPacketToDysonSphere<DysonLaunchDataPacket>(new DysonLaunchDataPacket(value), value.StarIndex);
				}
			}
			foreach (DysonLaunchData value2 in Snapshots.Values)
			{
				value2.BulletList.Clear();
				value2.RocketList.Clear();
				value2.BulletTick = 0;
				value2.RocketTick = 0;
			}
		}

		public void ImportPacket(DysonLaunchDataPacket packet)
		{
			Snapshots[packet.Data.StarIndex] = packet.Data;
			planetIds.Clear();
			for (int i = 0; i < GameMain.data.factoryCount; i++)
			{
				planetIds.Add(GameMain.data.factories[i].planetId);
			}
		}

		public void LaunchProjectile()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			int num = -1;
			foreach (DysonLaunchData value2 in Snapshots.Values)
			{
				DysonSphere val = GameMain.data.dysonSpheres[value2.StarIndex];
				if (val == null)
				{
					num = value2.StarIndex;
					continue;
				}
				while (value2.BulletCursor < value2.BulletList.Count)
				{
					if (value2.BulletList[value2.BulletCursor].Interval <= value2.BulletTick)
					{
						if (!planetIds.Contains(value2.BulletList[value2.BulletCursor].PlanetId))
						{
							AddBullet(val.swarm, value2.BulletList[value2.BulletCursor]);
						}
						int bulletCursor = value2.BulletCursor;
						value2.BulletCursor = bulletCursor + 1;
						value2.BulletTick = 0;
						continue;
					}
					byte bulletTick = value2.BulletTick;
					value2.BulletTick = (byte)(bulletTick + 1);
					break;
				}
				while (value2.RocketCursor < value2.RocketList.Count)
				{
					if (value2.RocketList[value2.RocketCursor].Interval <= value2.RocketTick)
					{
						if (!planetIds.Contains(value2.RocketList[value2.RocketCursor].PlanetId))
						{
							AddRocket(val, value2.RocketList[value2.RocketCursor]);
						}
						int bulletCursor = value2.RocketCursor;
						value2.RocketCursor = bulletCursor + 1;
						value2.RocketTick = 0;
						continue;
					}
					byte bulletTick = value2.RocketTick;
					value2.RocketTick = (byte)(bulletTick + 1);
					break;
				}
				if (value2.BulletCursor == value2.BulletList.Count && value2.RocketCursor == value2.RocketList.Count)
				{
					num = value2.StarIndex;
				}
			}
			if (num >= 0)
			{
				Snapshots.TryRemove(num, out var _);
			}
		}

		private static void AddBullet(DysonSwarm swarm, Projectile projectile)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			ref AstroData[] astrosData = ref GameMain.data.galaxy.astrosData;
			int targetId = projectile.TargetId;
			if (swarm.OrbitExist(targetId))
			{
				VectorLF3 uPos = astrosData[projectile.PlanetId / 100 * 100].uPos;
				SailBullet val = default(SailBullet);
				val.lBegin = projectile.LocalPos;
				val.uBegin = astrosData[projectile.PlanetId].uPos + Maths.QRotateLF(astrosData[projectile.PlanetId].uRot, VectorLF3.op_Implicit(projectile.LocalPos));
				VectorLF3 val2 = VectorLF3.Cross(VectorLF3.op_Implicit(swarm.orbits[targetId].up), uPos - val.uBegin);
				val.uEnd = uPos + ((VectorLF3)(ref val2)).normalized * (double)swarm.orbits[targetId].radius;
				val2 = val.uEnd - val.uBegin;
				val.maxt = (float)(((VectorLF3)(ref val2)).magnitude / 4000.0);
				val2 = VectorLF3.Cross(val.uEnd - uPos, VectorLF3.op_Implicit(swarm.orbits[targetId].up));
				val.uEndVel = VectorLF3.op_Implicit(((VectorLF3)(ref val2)).normalized * Math.Sqrt(swarm.dysonSphere.gravity / swarm.orbits[targetId].radius));
				swarm.AddBullet(val, targetId);
			}
		}

		private static void AddRocket(DysonSphere sphere, Projectile projectile)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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)
			ref AstroData[] astrosData = ref GameMain.data.galaxy.astrosData;
			int num = projectile.TargetId >> 12;
			int num2 = projectile.TargetId & 0xFFF;
			DysonNode val = sphere.FindNode(num, num2);
			if (val != null)
			{
				DysonRocket val2 = default(DysonRocket);
				val2.planetId = projectile.PlanetId;
				val2.uPos = astrosData[projectile.PlanetId].uPos + Maths.QRotateLF(astrosData[projectile.PlanetId].uRot, VectorLF3.op_Implicit(projectile.LocalPos + ((Vector3)(ref projectile.LocalPos)).normalized * 6.1f));
				val2.uRot = astrosData[projectile.PlanetId].uRot * Maths.SphericalRotation(projectile.LocalPos, 0f) * Quaternion.Euler(-90f, 0f, 0f);
				val2.uVel = val2.uRot * Vector3.forward;
				val2.uSpeed = 0f;
				val2.launch = ((Vector3)(ref projectile.LocalPos)).normalized;
				sphere.AddDysonRocket(val2, val);
			}
		}
	}
}
namespace NebulaWorld.Trash
{
	public class TrashManager : IDisposable
	{
		public readonly ToggleSwitch IsIncomingRequest = new ToggleSwitch();

		public readonly ToggleSwitch RemoveTrashFromOtherPlayers = new ToggleSwitch();

		public int PlanetId { get; set; }

		public Vector3 LocalPos { get; set; }

		public int ClientTrashCount { get; set; }

		public void Dispose()
		{
			GC.SuppressFinalize(this);
		}

		public static void SetNextTrashId(int trashId)
		{
			TrashContainer container = GameMain.data.trashSystem.container;
			if (trashId >= container.trashCursor)
			{
				container.trashCursor = trashId;
				while (container.trashCursor >= container.trashCapacity)
				{
					container.SetTrashCapacity(container.trashCapacity * 2);
				}
			}
			else
			{
				container.trashRecycle[0] = trashId;
				container.trashRecycleCursor = 1;
			}
		}

		public void Refresh()
		{
			if (Multiplayer.Session.IsServer)
			{
				return;
			}
			ClientTrashCount = 0;
			int num = GameMain.localPlanet?.id ?? (-1);
			TrashContainer container = GameMain.data.trashSystem.container;
			TrashObject[] trashObjPool = container.trashObjPool;
			TrashData[] trashDataPool = container.trashDataPool;
			for (int i = 0; i < container.trashCursor; i++)
			{
				if (trashObjPool[i].item > 0 && (trashDataPool[i].life == 0 || trashDataPool[i].nearPlanetId == num))
				{
					ClientTrashCount++;
				}
			}
		}
	}
}
namespace NebulaWorld.Statistics
{
	public class StatisticsManager : IDisposable
	{
		private sealed class ThreadSafe
		{
			internal readonly Dictionary<ushort, NebulaConnection> Requestors = new Dictionary<ushort, NebulaConnection>();
		}

		public readonly ToggleSwitch IsIncomingRequest = new ToggleSwitch();

		private readonly ThreadSafe threadSafe = new ThreadSafe();

		private Dictionary<int, int> factoryIndexMap = new Dictionary<int, int>();

		private PlanetData[] planetDataMap = (PlanetData[])(object)new PlanetData[GameMain.data.factories.Length];

		private List<StatisticalSnapShot> statisticalSnapShots = new List<StatisticalSnapShot>();

		public bool IsStatisticsNeeded { get; set; }

		public long[] PowerEnergyStoredData { get; set; }

		public int FactoryCount { get; set; }

		public int TechHashedFor10Frames { get; set; }

		public void Dispose()
		{
			statisticalSnapShots = null;
			planetDataMap = null;
			factoryIndexMap = null;
			GC.SuppressFinalize(this);
		}

		private Locker GetRequestors(out Dictionary<ushort, NebulaConnection> requestors)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return CollectionExtensions.GetLocked<Dictionary<ushort, NebulaConnection>>(threadSafe.Requestors, ref requestors);
		}

		private void ClearCapturedData()
		{
			statisticalSnapShots.Clear();
		}

		public void CaptureStatisticalSnapshot()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			if (!IsStatisticsNeeded || GameMain.statistics?.production == null)
			{
				return;
			}
			int factoryCount = GameMain.data.factoryCount;
			StatisticalSnapShot val = new StatisticalSnapShot(GameMain.gameTick, factoryCount);
			for (ushort num = 0; num < factoryCount; num++)
			{
				FactoryProductionStat val2 = GameMain.statistics.production.factoryStatPool[num];
				for (ushort num2 = 0; num2 < val2.productRegister.Length; num2++)
				{
					if (val2.productRegister[num2] != 0)
					{
						val.ProductionChangesPerFactory[num].Add(new ProductionChangeStruct(true, num2, val2.productRegister[num2]));
					}
					if (val2.consumeRegister[num2] != 0)
					{
						val.ProductionChangesPerFactory[num].Add(new ProductionChangeStruct(false, num2, val2.consumeRegister[num2]));
					}
				}
				val.PowerGenerationRegister[num] = val2.powerGenRegister;
				val.PowerConsumptionRegister[num] = val2.powerConRegister;
				val.PowerChargingRegister[num] = val2.powerChaRegister;
				val.PowerDischargingRegister[num] = val2.powerDisRegister;
				for (int i = 0; i < GameMain.data.factories[num].powerSystem.netCursor; i++)
				{
					val.EnergyStored[num] += GameMain.data.factories[num].powerSystem.netPool[i].energyStored;
				}
				val.HashRegister[num] = val2.hashRegister;
			}
			statisticalSnapShots.Add(val);
		}

		public void SendBroadcastIfNeeded()
		{
			//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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			if (!IsStatisticsNeeded)
			{
				return;
			}
			Dictionary<ushort, NebulaConnection> requestors;
			Locker requestors2 = GetRequestors(out requestors);
			try
			{
				if (requestors.Count <= 0)
				{
					return;
				}
				if (FactoryCount == GameMain.data.factoryCount)
				{
					Writer val = new Writer();
					StatisticUpdateDataPacket val2;
					try
					{
						ExportCurrentTickData(val.BinaryWriter);
						val2 = new StatisticUpdateDataPacket(val.CloseAndGetBytes());
					}
					finally
					{
						((IDisposable)val)?.Dispose();
					}
					foreach (KeyValuePair<ushort, NebulaConnection> item in requestors)
					{
						item.Value.SendPacket<StatisticUpdateDataPacket>(val2);
					}
				}
				else
				{
					Writer val3 = new Writer();
					StatisticsDataPacket val4;
					try
					{
						ExportAllData(val3.BinaryWriter);
						val4 = new StatisticsDataPacket(val3.CloseAndGetBytes());
					}
					finally
					{
						((IDisposable)val3)?.Dispose();
					}
					foreach (KeyValuePair<ushort, NebulaConnection> item2 in requestors)
					{
						item2.Value.SendPacket<StatisticsDataPacket>(val4);
					}
				}
				ClearCapturedData();
			}
			finally
			{
				((IDisposable)(Locker)(ref requestors2)).Dispose();
			}
		}

		private void ExportCurrentTickData(BinaryWriter bw)
		{
			bw.Write(statisticalSnapShots.Count);
			foreach (StatisticalSnapShot statisticalSnapShot in statisticalSnapShots)
			{
				statisticalSnapShot.Export(bw);
			}
		}

		public void RegisterPlayer(NebulaConnection nebulaConnection, ushort playerId)
		{
			//IL_0003: 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)
			Dictionary<ushort, NebulaConnection> requestors;
			Locker requestors2 = GetRequestors(out requestors);
			try
			{
				requestors.Add(playerId, nebulaConnection);
			}
			finally
			{
				((IDisposable)(Locker)(ref requestors2)).Dispose();
			}
			if (!IsStatisticsNeeded)
			{
				ClearCapturedData();
				IsStatisticsNeeded = true;
			}
		}

		public void UnRegisterPlayer(ushort playerId)
		{
			//IL_0003: 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)
			Dictionary<ushort, NebulaConnection> requestors;
			Locker requestors2 = GetRequestors(out requestors);
			try
			{
				if (requestors.Remove(playerId) && requestors.Count == 0)
				{
					IsStatisticsNeeded = false;
				}
			}
			finally
			{
				((IDisposable)(Locker)(ref requestors2)).Dispose();
			}
		}

		public void ExportAllData(BinaryWriter bw)
		{
			GameStatData statistics = GameMain.statistics;
			FactoryCount = GameMain.data.factoryCount;
			bw.Write(GameMain.data.factoryCount);
			for (int i = 0; i < GameMain.data.factoryCount; i++)
			{
				bw.Write(GameMain.data.factories[i].planetId);
			}
			for (int j = 0; j < GameMain.data.factoryCount; j++)
			{
				statistics.production.factoryStatPool[j].Export(bw.BaseStream, bw);
			}
			bw.Write(statistics.techHashedHistory.Length);
			int[] techHashedHistory = statistics.techHashedHistory;
			foreach (int value in techHashedHistory)
			{
				bw.Write(value);
			}
		}

		public void ImportAllData(BinaryReader br)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			GameStatData statistics = GameMain.statistics;
			FactoryCount = br.ReadInt32();
			for (int i = 0; i < FactoryCount; i++)
			{
				PlanetData val = GameMain.galaxy.PlanetById(br.ReadInt32());
				if (planetDataMap[i] == null || planetDataMap[i] != val)
				{
					planetDataMap[i] = val;
					factoryIndexMap[val.id] = i;
				}
			}
			for (int j = 0; j < FactoryCount; j++)
			{
				if (statistics.production.factoryStatPool[j] == null)
				{
					statistics.production.factoryStatPool[j] = new FactoryProductionStat();
					statistics.production.factoryStatPool[j].Init();
				}
				statistics.production.factoryStatPool[j].Import(br.BaseStream, br);
			}
			int num = br.ReadInt32();
			if (num > statistics.techHashedHistory.Length)
			{
				statistics.techHashedHistory = new int[num];
			}
			for (int k = 0; k < num; k++)
			{
				statistics.techHashedHistory[k] = br.ReadInt32();
			}
			UIRoot.instance.uiGame.statWindow.RefreshAll();
		}

		public PlanetData GetPlanetData(int factoryIndex)
		{
			return planetDataMap[factoryIndex];
		}

		public int GetFactoryIndex(PlanetData planet)
		{
			if (factoryIndexMap.TryGetValue(planet.id, out var value))
			{
				return value;
			}
			return -1;
		}

		public long UpdateTotalChargedEnergy(int factoryIndex)
		{
			return PowerEnergyStoredData[factoryIndex];
		}
	}
}
namespace NebulaWorld.SocialIntegration
{
	public static class DiscordManager
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ActivityJoinRequestHandler <0>__ActivityManager_OnActivityJoinRequest;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static SendRequestReplyHandler <>9__7_0;

			public static UpdateActivityHandler <>9__9_0;

			internal void <ActivityManager_OnActivityJoinRequest>b__7_0(Result result)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				Log.Info(((int)result == 0) ? "Accepted request." : "Could not accept request.");
			}

			internal void <UpdateActivity>b__9_0(Result result)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				if ((int)result == 0)
				{
					Log.Info("Updated Discord activity");
				}
				else
				{
					Log.Warn("Could not update Discord activity");
				}
			}
		}

		private static Discord client;

		private static ActivityManager ActivityManager;

		private static Activity activity;

		private static readonly Random random = new Random();

		private static int SecretLength => 128;

		public static void Setup(ActivityJoinHandler activityJoinHandler)
		{
			//IL_0030: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			if (!Config.Options.EnableDiscordRPC)
			{
				Log.Info("Discord RPC support not enabled.");
				return;
			}
			try
			{
				client = new Discord(968766006182961182L, 1uL);
			}
			catch (ResultException val)
			{
				ResultException val2 = val;
				Log.Warn((object)val2);
				Cleanup();
				return;
			}
			ActivityManager = client.GetActivityManager();
			ActivityManager.RegisterCommand(Environment.CommandLine);
			FileInfo fileInfo = new FileInfo(Environment.GetCommandLineArgs()[0]);
			if (fileInfo.DirectoryName != null)
			{
				string path = Path.Combine(fileInfo.DirectoryName, "steam_appid.txt");
				if (!File.Exists(path))
				{
					File.WriteAllText(path, "1366540");
				}
			}
			Log.Info("Initialized Discord RPC");
			Activity val3 = default(Activity);
			val3.State = "In Menus";
			val3.Timestamps.Start = DateTimeOffset.Now.ToUnixTimeSeconds();
			val3.Party.Id = CreateSecret();
			val3.Party.Size = default(PartySize);
			val3.Instance = true;
			activity = val3;
			UpdateActivity();
			ActivityManager activityManager = ActivityManager;
			object obj = <>O.<0>__ActivityManager_OnActivityJoinRequest;
			if (obj == null)
			{
				ActivityJoinRequestHandler val4 = ActivityManager_OnActivityJoinRequest;
				<>O.<0>__ActivityManager_OnActivityJoinRequest = val4;
				obj = (object)val4;
			}
			activityManager.OnActivityJoinRequest += (ActivityJoinRequestHandler)obj;
			ActivityManager.OnActivityJoin += activityJoinHandler;
		}

		private static void ActivityManager_OnActivityJoinRequest(ref User user)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			Log.Info("Received Discord join request from user " + user.Username[0] + new string('*', user.Username.Length - 2) + user.Username[user.Username.Length - 1]);
			if (!Config.Options.AutoAcceptDiscordJoinRequests)
			{
				return;
			}
			ActivityManager activityManager = ActivityManager;
			long id = user.Id;
			object obj = <>c.<>9__7_0;
			if (obj == null)
			{
				SendRequestReplyHandler val = delegate(Result result)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					Log.Info(((int)result == 0) ? "Accepted request." : "Could not accept request.");
				};
				<>c.<>9__7_0 = val;
				obj = (object)val;
			}
			activityManager.SendRequestReply(id, (ActivityJoinRequestReply)1, (SendRequestReplyHandler)obj);
		}

		public static void Update()
		{
			//IL_0022: Expected O, but got Unknown
			if (!Config.Options.EnableDiscordRPC || client == null)
			{
				return;
			}
			try
			{
				client.RunCallbacks();
			}
			catch (ResultException val)
			{
				ResultException val2 = val;
				Log.Warn((object)val2);
				Cleanup();
			}
		}

		private static void UpdateActivity()
		{
			//IL_0005: 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)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			ActivityManager activityManager = ActivityManager;
			Activity val = activity;
			object obj = <>c.<>9__9_0;
			if (obj == null)
			{
				UpdateActivityHandler val2 = delegate(Result result)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					if ((int)r

Open.Nat.dll

Decompiled 2 weeks ago
#define TRACE
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Open.Nat")]
[assembly: AssemblyDescription(".NET Library for automatic network address translation")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Open.Nat")]
[assembly: AssemblyCopyright("Copyright Alan McGovern, Ben Motmans, Lucas Ontivero ©  2006-2014")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c8e81e95-9f15-4eb8-8982-3d2c9cd95dee")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: CLSCompliant(false)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Open.Nat;

internal sealed class Finalizer
{
	~Finalizer()
	{
		NatDiscoverer.TraceSource.LogInfo("Closing ports opened in this session");
		NatDiscoverer.RenewTimer.Dispose();
		NatDiscoverer.ReleaseSessionMappings();
	}
}
internal class Guard
{
	private Guard()
	{
	}

	internal static void IsInRange(int paramValue, int lowerBound, int upperBound, string paramName)
	{
		if (paramValue < lowerBound || paramValue > upperBound)
		{
			throw new ArgumentOutOfRangeException(paramName);
		}
	}

	internal static void IsTrue(bool exp, string paramName)
	{
		if (!exp)
		{
			throw new ArgumentOutOfRangeException(paramName);
		}
	}

	internal static void IsNotNull(object obj, string paramName)
	{
		if (obj == null)
		{
			throw new ArgumentNullException(paramName);
		}
	}
}
public abstract class NatDevice
{
	private readonly HashSet<Mapping> _openedMapping = new HashSet<Mapping>();

	protected DateTime LastSeen { get; private set; }

	internal void Touch()
	{
		LastSeen = DateTime.Now;
	}

	public abstract Task CreatePortMapAsync(Mapping mapping);

	public abstract Task DeletePortMapAsync(Mapping mapping);

	public abstract Task<IEnumerable<Mapping>> GetAllMappingsAsync();

	public abstract Task<IPAddress> GetExternalIPAsync();

	public abstract Task<Mapping> GetSpecificMappingAsync(Protocol protocol, int port);

	protected void RegisterMapping(Mapping mapping)
	{
		_openedMapping.Remove(mapping);
		_openedMapping.Add(mapping);
	}

	protected void UnregisterMapping(Mapping mapping)
	{
		_openedMapping.RemoveWhere((Mapping x) => x.Equals(mapping));
	}

	internal void ReleaseMapping(IEnumerable<Mapping> mappings)
	{
		int num = mappings.ToArray().Length;
		NatDiscoverer.TraceSource.LogInfo("{0} ports to close", num);
		for (int i = 0; i < num; i = checked(i + 1))
		{
			Mapping mapping = _openedMapping.ElementAt(i);
			try
			{
				DeletePortMapAsync(mapping);
				NatDiscoverer.TraceSource.LogInfo(string.Concat(mapping, " port successfully closed"));
			}
			catch (Exception)
			{
				NatDiscoverer.TraceSource.LogError(string.Concat(mapping, " port couldn't be close"));
			}
		}
	}

	internal void ReleaseAll()
	{
		ReleaseMapping(_openedMapping);
	}

	internal void ReleaseSessionMappings()
	{
		IEnumerable<Mapping> mappings = _openedMapping.Where((Mapping m) => m.LifetimeType == MappingLifetime.Session);
		ReleaseMapping(mappings);
	}

	internal async Task RenewMappings()
	{
		IEnumerable<Mapping> source = _openedMapping.Where((Mapping x) => x.ShoundRenew());
		Mapping[] array = source.ToArray();
		foreach (Mapping mapping in array)
		{
			await RenewMapping(mapping);
		}
	}

	private async Task RenewMapping(Mapping mapping)
	{
		Mapping renewMapping = new Mapping(mapping);
		try
		{
			renewMapping.Expiration = DateTime.UtcNow.AddSeconds(mapping.Lifetime);
			NatDiscoverer.TraceSource.LogInfo("Renewing mapping {0}", renewMapping);
			await CreatePortMapAsync(renewMapping);
			NatDiscoverer.TraceSource.LogInfo("Next renew scheduled at: {0}", renewMapping.Expiration.ToLocalTime().TimeOfDay);
		}
		catch (Exception)
		{
			NatDiscoverer.TraceSource.LogWarn("Renew {0} failed", mapping);
		}
	}
}
public enum Protocol
{
	Tcp,
	Udp
}
internal class DeviceEventArgs : EventArgs
{
	public NatDevice Device { get; private set; }

	public DeviceEventArgs(NatDevice device)
	{
		Device = device;
	}
}
[Serializable]
public class MappingException : Exception
{
	public int ErrorCode { get; private set; }

	public string ErrorText { get; private set; }

	internal MappingException()
	{
	}

	internal MappingException(string message)
		: base(message)
	{
	}

	internal MappingException(int errorCode, string errorText)
		: base($"Error {errorCode}: {errorText}")
	{
		ErrorCode = errorCode;
		ErrorText = errorText;
	}

	internal MappingException(string message, Exception innerException)
		: base(message, innerException)
	{
	}

	protected MappingException(SerializationInfo info, StreamingContext context)
		: base(info, context)
	{
	}

	[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
	public override void GetObjectData(SerializationInfo info, StreamingContext context)
	{
		if (info == null)
		{
			throw new ArgumentNullException("info");
		}
		ErrorCode = info.GetInt32("errorCode");
		ErrorText = info.GetString("errorText");
		base.GetObjectData(info, context);
	}
}
internal interface ISearcher
{
	void Search(CancellationToken cancellationToken);

	IEnumerable<NatDevice> Receive();

	NatDevice AnalyseReceivedResponse(IPAddress localAddress, byte[] response, IPEndPoint endpoint);
}
internal enum MappingLifetime
{
	Permanent,
	Session,
	Manual,
	ForcedSession
}
public class Mapping
{
	private DateTime _expiration;

	private int _lifetime;

	internal MappingLifetime LifetimeType { get; set; }

	public string Description { get; internal set; }

	public IPAddress PrivateIP { get; internal set; }

	public Protocol Protocol { get; internal set; }

	public int PrivatePort { get; internal set; }

	public IPAddress PublicIP { get; internal set; }

	public int PublicPort { get; internal set; }

	public int Lifetime
	{
		get
		{
			return _lifetime;
		}
		internal set
		{
			switch (value)
			{
			case int.MaxValue:
				LifetimeType = MappingLifetime.Session;
				_lifetime = 600;
				_expiration = DateTime.UtcNow.AddSeconds(_lifetime);
				break;
			case 0:
				LifetimeType = MappingLifetime.Permanent;
				_lifetime = 0;
				_expiration = DateTime.UtcNow;
				break;
			default:
				LifetimeType = MappingLifetime.Manual;
				_lifetime = value;
				_expiration = DateTime.UtcNow.AddSeconds(_lifetime);
				break;
			}
		}
	}

	public DateTime Expiration
	{
		get
		{
			return _expiration;
		}
		internal set
		{
			_expiration = value;
			_lifetime = checked((int)(_expiration - DateTime.UtcNow).TotalSeconds);
		}
	}

	internal Mapping(Protocol protocol, IPAddress privateIP, int privatePort, int publicPort)
		: this(protocol, privateIP, privatePort, publicPort, 0, "Open.Nat")
	{
	}

	public Mapping(Protocol protocol, IPAddress privateIP, int privatePort, int publicPort, int lifetime, string description)
	{
		Guard.IsInRange(privatePort, 0, 65535, "privatePort");
		Guard.IsInRange(publicPort, 0, 65535, "publicPort");
		Guard.IsInRange(lifetime, 0, int.MaxValue, "lifetime");
		Guard.IsTrue(protocol == Protocol.Tcp || protocol == Protocol.Udp, "protocol");
		Guard.IsNotNull(privateIP, "privateIP");
		Protocol = protocol;
		PrivateIP = privateIP;
		PrivatePort = privatePort;
		PublicIP = IPAddress.None;
		PublicPort = publicPort;
		Lifetime = lifetime;
		Description = description;
	}

	public Mapping(Protocol protocol, int privatePort, int publicPort)
		: this(protocol, IPAddress.None, privatePort, publicPort, 0, "Open.NAT")
	{
	}

	public Mapping(Protocol protocol, int privatePort, int publicPort, string description)
		: this(protocol, IPAddress.None, privatePort, publicPort, int.MaxValue, description)
	{
	}

	public Mapping(Protocol protocol, int privatePort, int publicPort, int lifetime, string description)
		: this(protocol, IPAddress.None, privatePort, publicPort, lifetime, description)
	{
	}

	internal Mapping(Mapping mapping)
	{
		PrivateIP = mapping.PrivateIP;
		PrivatePort = mapping.PrivatePort;
		Protocol = mapping.Protocol;
		PublicIP = mapping.PublicIP;
		PublicPort = mapping.PublicPort;
		LifetimeType = mapping.LifetimeType;
		Description = mapping.Description;
		_lifetime = mapping._lifetime;
		_expiration = mapping._expiration;
	}

	public bool IsExpired()
	{
		if (LifetimeType != 0 && LifetimeType != MappingLifetime.ForcedSession)
		{
			return Expiration < DateTime.UtcNow;
		}
		return false;
	}

	internal bool ShoundRenew()
	{
		if (LifetimeType == MappingLifetime.Session)
		{
			return IsExpired();
		}
		return false;
	}

	public override bool Equals(object obj)
	{
		if (obj == null)
		{
			return false;
		}
		if (this == obj)
		{
			return true;
		}
		if (!(obj is Mapping mapping))
		{
			return false;
		}
		if (PublicPort == mapping.PublicPort)
		{
			return PrivatePort == mapping.PrivatePort;
		}
		return false;
	}

	public override int GetHashCode()
	{
		return (((PublicPort * 397) ^ ((PrivateIP != null) ? PrivateIP.GetHashCode() : 0)) * 397) ^ PrivatePort;
	}

	public override string ToString()
	{
		return string.Format("{0} {1} --> {2}:{3} ({4})", (Protocol == Protocol.Tcp) ? "Tcp" : "Udp", PublicPort, PrivateIP, PrivatePort, Description);
	}
}
[Serializable]
public class NatDeviceNotFoundException : Exception
{
	public NatDeviceNotFoundException()
	{
	}

	public NatDeviceNotFoundException(string message)
		: base(message)
	{
	}

	public NatDeviceNotFoundException(string message, Exception innerException)
		: base(message, innerException)
	{
	}

	protected NatDeviceNotFoundException(SerializationInfo info, StreamingContext context)
		: base(info, context)
	{
	}
}
public class NatDiscoverer
{
	public static readonly TraceSource TraceSource = new TraceSource("Open.NAT");

	private static readonly Dictionary<string, NatDevice> Devices = new Dictionary<string, NatDevice>();

	private static readonly Finalizer Finalizer = new Finalizer();

	internal static readonly Timer RenewTimer = new Timer(RenewMappings, null, 5000, 2000);

	public async Task<NatDevice> DiscoverDeviceAsync()
	{
		CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(3000);
		return await DiscoverDeviceAsync(PortMapper.Pmp | PortMapper.Upnp, cancellationTokenSource);
	}

	public async Task<NatDevice> DiscoverDeviceAsync(PortMapper portMapper, CancellationTokenSource cancellationTokenSource)
	{
		Guard.IsTrue(portMapper.HasFlag(PortMapper.Upnp) || portMapper.HasFlag(PortMapper.Pmp), "portMapper");
		Guard.IsNotNull(cancellationTokenSource, "cancellationTokenSource");
		NatDevice natDevice = (await DiscoverAsync(portMapper, onlyOne: true, cancellationTokenSource)).FirstOrDefault();
		if (natDevice == null)
		{
			TraceSource.LogInfo("Device not found. Common reasons:");
			TraceSource.LogInfo("\t* No device is present or,");
			TraceSource.LogInfo("\t* Upnp is disabled in the router or");
			TraceSource.LogInfo("\t* Antivirus software is filtering SSDP (discovery protocol).");
			throw new NatDeviceNotFoundException();
		}
		return natDevice;
	}

	public async Task<IEnumerable<NatDevice>> DiscoverDevicesAsync(PortMapper portMapper, CancellationTokenSource cancellationTokenSource)
	{
		Guard.IsTrue(portMapper.HasFlag(PortMapper.Upnp) || portMapper.HasFlag(PortMapper.Pmp), "portMapper");
		Guard.IsNotNull(cancellationTokenSource, "cancellationTokenSource");
		return (await DiscoverAsync(portMapper, onlyOne: false, cancellationTokenSource)).ToArray();
	}

	private async Task<IEnumerable<NatDevice>> DiscoverAsync(PortMapper portMapper, bool onlyOne, CancellationTokenSource cts)
	{
		TraceSource.LogInfo("Start Discovery");
		List<Task<IEnumerable<NatDevice>>> searcherTasks = new List<Task<IEnumerable<NatDevice>>>();
		if (portMapper.HasFlag(PortMapper.Upnp))
		{
			UpnpSearcher upnpSearcher = new UpnpSearcher(new IPAddressesProvider());
			upnpSearcher.DeviceFound = (EventHandler<DeviceEventArgs>)Delegate.Combine(upnpSearcher.DeviceFound, (EventHandler<DeviceEventArgs>)delegate
			{
				if (onlyOne)
				{
					cts.Cancel();
				}
			});
			searcherTasks.Add(upnpSearcher.Search(cts.Token));
		}
		if (portMapper.HasFlag(PortMapper.Pmp))
		{
			PmpSearcher pmpSearcher = new PmpSearcher(new IPAddressesProvider());
			pmpSearcher.DeviceFound = (EventHandler<DeviceEventArgs>)Delegate.Combine(pmpSearcher.DeviceFound, (EventHandler<DeviceEventArgs>)delegate
			{
				if (onlyOne)
				{
					cts.Cancel();
				}
			});
			searcherTasks.Add(pmpSearcher.Search(cts.Token));
		}
		await Task.WhenAll(searcherTasks);
		TraceSource.LogInfo("Stop Discovery");
		IEnumerable<NatDevice> enumerable = searcherTasks.SelectMany((Task<IEnumerable<NatDevice>> x) => x.Result);
		foreach (NatDevice item in enumerable)
		{
			string key = item.ToString();
			if (Devices.TryGetValue(key, out var value))
			{
				value.Touch();
			}
			else
			{
				Devices.Add(key, item);
			}
		}
		return enumerable;
	}

	public static void ReleaseAll()
	{
		foreach (NatDevice value in Devices.Values)
		{
			value.ReleaseAll();
		}
	}

	internal static void ReleaseSessionMappings()
	{
		foreach (NatDevice value in Devices.Values)
		{
			value.ReleaseSessionMappings();
		}
	}

	private static void RenewMappings(object state)
	{
		Task.Factory.StartNew((Func<Task>)async delegate
		{
			foreach (NatDevice value in Devices.Values)
			{
				await value.RenewMappings();
			}
		});
	}
}
internal class PmpSearcher : Searcher
{
	private readonly IIPAddressesProvider _ipprovider;

	private Dictionary<UdpClient, IEnumerable<IPEndPoint>> _gatewayLists;

	private int _timeout;

	internal PmpSearcher(IIPAddressesProvider ipprovider)
	{
		_ipprovider = ipprovider;
		_timeout = 250;
		CreateSocketsAndAddGateways();
	}

	private void CreateSocketsAndAddGateways()
	{
		Sockets = new List<UdpClient>();
		_gatewayLists = new Dictionary<UdpClient, IEnumerable<IPEndPoint>>();
		try
		{
			List<IPEndPoint> list = (from ip in _ipprovider.GatewayAddresses()
				select new IPEndPoint(ip, 5351)).ToList();
			if (!list.Any())
			{
				list.AddRange(from ip in _ipprovider.DnsAddresses()
					select new IPEndPoint(ip, 5351));
			}
			if (!list.Any())
			{
				return;
			}
			foreach (IPAddress item in _ipprovider.UnicastAddresses())
			{
				UdpClient udpClient;
				try
				{
					udpClient = new UdpClient(new IPEndPoint(item, 0));
				}
				catch (SocketException)
				{
					continue;
				}
				_gatewayLists.Add(udpClient, list);
				Sockets.Add(udpClient);
			}
		}
		catch (Exception ex2)
		{
			NatDiscoverer.TraceSource.LogError("There was a problem finding gateways: " + ex2);
		}
	}

	protected override void Discover(UdpClient client, CancellationToken cancelationToken)
	{
		NextSearch = DateTime.UtcNow.AddMilliseconds(_timeout);
		checked
		{
			_timeout *= 2;
			if (_timeout >= 3000)
			{
				_timeout = 250;
				NextSearch = DateTime.UtcNow.AddSeconds(10.0);
				return;
			}
			byte[] array = new byte[2];
			foreach (IPEndPoint item in _gatewayLists[client])
			{
				if (cancelationToken.IsCancellationRequested)
				{
					break;
				}
				client.Send(array, array.Length, item);
			}
		}
	}

	private bool IsSearchAddress(IPAddress address)
	{
		return _gatewayLists.Values.SelectMany((IEnumerable<IPEndPoint> x) => x).Any((IPEndPoint x) => x.Address.Equals(address));
	}

	public override NatDevice AnalyseReceivedResponse(IPAddress localAddress, byte[] response, IPEndPoint endpoint)
	{
		if (!IsSearchAddress(endpoint.Address) || response.Length != 12 || response[0] != 0 || response[1] != 128)
		{
			return null;
		}
		int num = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(response, 2));
		if (num != 0)
		{
			NatDiscoverer.TraceSource.LogError("Non zero error: {0}", num);
		}
		IPAddress publicAddress = new IPAddress(new byte[4]
		{
			response[8],
			response[9],
			response[10],
			response[11]
		});
		_timeout = 250;
		return new PmpNatDevice(endpoint.Address, publicAddress);
	}
}
internal static class PmpConstants
{
	public const byte Version = 0;

	public const byte OperationExternalAddressRequest = 0;

	public const byte OperationCodeUdp = 1;

	public const byte OperationCodeTcp = 2;

	public const byte ServerNoop = 128;

	public const int ClientPort = 5350;

	public const int ServerPort = 5351;

	public const int RetryDelay = 250;

	public const int RetryAttempts = 9;

	public const int RecommendedLeaseTime = 3600;

	public const int DefaultLeaseTime = 3600;

	public const short ResultCodeSuccess = 0;

	public const short ResultCodeUnsupportedVersion = 1;

	public const short ResultCodeNotAuthorized = 2;

	public const short ResultCodeNetworkFailure = 3;

	public const short ResultCodeOutOfResources = 4;

	public const short ResultCodeUnsupportedOperationCode = 5;
}
internal sealed class PmpNatDevice : NatDevice
{
	private readonly IPAddress _publicAddress;

	internal IPAddress LocalAddress { get; private set; }

	internal PmpNatDevice(IPAddress localAddress, IPAddress publicAddress)
	{
		LocalAddress = localAddress;
		_publicAddress = publicAddress;
	}

	public override async Task CreatePortMapAsync(Mapping mapping)
	{
		await InternalCreatePortMapAsync(mapping, create: true).TimeoutAfter(TimeSpan.FromSeconds(4.0));
		RegisterMapping(mapping);
	}

	public override async Task DeletePortMapAsync(Mapping mapping)
	{
		await InternalCreatePortMapAsync(mapping, create: false).TimeoutAfter(TimeSpan.FromSeconds(4.0));
		UnregisterMapping(mapping);
	}

	public override Task<IEnumerable<Mapping>> GetAllMappingsAsync()
	{
		throw new NotSupportedException();
	}

	public override Task<IPAddress> GetExternalIPAsync()
	{
		return Task.Run(() => _publicAddress).TimeoutAfter(TimeSpan.FromSeconds(4.0));
	}

	public override Task<Mapping> GetSpecificMappingAsync(Protocol protocol, int port)
	{
		throw new NotSupportedException("NAT-PMP does not specify a way to get a specific port map");
	}

	private async Task<Mapping> InternalCreatePortMapAsync(Mapping mapping, bool create)
	{
		List<byte> list = new List<byte>();
		list.Add(0);
		list.Add((byte)((mapping.Protocol != 0) ? 1 : 2));
		list.Add(0);
		list.Add(0);
		list.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(checked((short)mapping.PrivatePort))));
		list.AddRange(BitConverter.GetBytes((short)(create ? IPAddress.HostToNetworkOrder(checked((short)mapping.PublicPort)) : 0)));
		list.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(mapping.Lifetime)));
		checked
		{
			try
			{
				byte[] buffer = list.ToArray();
				int attempt = 0;
				int delay = 250;
				using UdpClient udpClient = new UdpClient();
				CreatePortMapListen(udpClient, mapping);
				while (attempt < 9)
				{
					await udpClient.SendAsync(buffer, buffer.Length, new IPEndPoint(LocalAddress, 5351));
					attempt++;
					delay *= 2;
					Thread.Sleep(delay);
				}
			}
			catch (Exception ex)
			{
				string arg = (create ? "create" : "delete");
				string text = $"Failed to {arg} portmap (protocol={mapping.Protocol}, private port={mapping.PrivatePort})";
				NatDiscoverer.TraceSource.LogError(text);
				MappingException innerException = ex as MappingException;
				throw new MappingException(text, innerException);
			}
			return mapping;
		}
	}

	private void CreatePortMapListen(UdpClient udpClient, Mapping mapping)
	{
		IPEndPoint remoteEP = new IPEndPoint(LocalAddress, 5351);
		byte[] array;
		do
		{
			array = udpClient.Receive(ref remoteEP);
		}
		while (array.Length < 16 || array[0] != 0);
		checked
		{
			byte num = (byte)(array[1] & 0x7F);
			Protocol protocol = Protocol.Tcp;
			if (num == 1)
			{
				protocol = Protocol.Udp;
			}
			short num2 = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(array, 2));
			IPAddress.NetworkToHostOrder(BitConverter.ToInt32(array, 4));
			short num3 = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(array, 8));
			short num4 = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(array, 10));
			uint num5 = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(array, 12));
			if (num3 < 0 || num4 < 0 || num2 != 0)
			{
				string[] array2 = new string[6] { "Success", "Unsupported Version", "Not Authorized/Refused (e.g. box supports mapping, but user has turned feature off)", "Network Failure (e.g. NAT box itself has not obtained a DHCP lease)", "Out of resources (NAT box cannot create any more mappings at this time)", "Unsupported opcode" };
				throw new MappingException(num2, array2[num2]);
			}
			if (num5 != 0)
			{
				mapping.PublicPort = num4;
				mapping.Protocol = protocol;
				mapping.Expiration = DateTime.Now.AddSeconds(num5);
			}
		}
	}

	public override string ToString()
	{
		return $"Local Address: {LocalAddress}\nPublic IP: {_publicAddress}\nLast Seen: {base.LastSeen}";
	}
}
[Flags]
public enum PortMapper
{
	Pmp = 1,
	Upnp = 2
}
internal abstract class Searcher
{
	private readonly List<NatDevice> _devices = new List<NatDevice>();

	protected List<UdpClient> Sockets;

	public EventHandler<DeviceEventArgs> DeviceFound;

	internal DateTime NextSearch = DateTime.UtcNow;

	public async Task<IEnumerable<NatDevice>> Search(CancellationToken cancelationToken)
	{
		await Task.Factory.StartNew((Action<object?>)delegate
		{
			NatDiscoverer.TraceSource.LogInfo("Searching for: {0}", GetType().Name);
			while (!cancelationToken.IsCancellationRequested)
			{
				Discover(cancelationToken);
				Receive(cancelationToken);
			}
			CloseSockets();
		}, (object?)cancelationToken);
		return _devices;
	}

	private void Discover(CancellationToken cancelationToken)
	{
		if (DateTime.UtcNow < NextSearch)
		{
			return;
		}
		foreach (UdpClient socket in Sockets)
		{
			try
			{
				Discover(socket, cancelationToken);
			}
			catch (Exception ex)
			{
				NatDiscoverer.TraceSource.LogError("Error searching {0} - Details:", GetType().Name);
				NatDiscoverer.TraceSource.LogError(ex.ToString());
			}
		}
	}

	private void Receive(CancellationToken cancelationToken)
	{
		foreach (UdpClient item in Sockets.Where((UdpClient x) => x.Available > 0))
		{
			if (cancelationToken.IsCancellationRequested)
			{
				break;
			}
			IPAddress address = ((IPEndPoint)item.Client.LocalEndPoint).Address;
			IPEndPoint remoteEP = new IPEndPoint(IPAddress.None, 0);
			byte[] response = item.Receive(ref remoteEP);
			NatDevice natDevice = AnalyseReceivedResponse(address, response, remoteEP);
			if (natDevice != null)
			{
				RaiseDeviceFound(natDevice);
			}
		}
	}

	protected abstract void Discover(UdpClient client, CancellationToken cancelationToken);

	public abstract NatDevice AnalyseReceivedResponse(IPAddress localAddress, byte[] response, IPEndPoint endpoint);

	public void CloseSockets()
	{
		foreach (UdpClient socket in Sockets)
		{
			socket.Close();
		}
	}

	private void RaiseDeviceFound(NatDevice device)
	{
		_devices.Add(device);
		DeviceFound?.Invoke(this, new DeviceEventArgs(device));
	}
}
internal class UpnpSearcher : Searcher
{
	private readonly IIPAddressesProvider _ipprovider;

	private readonly IDictionary<Uri, NatDevice> _devices;

	private readonly Dictionary<IPAddress, DateTime> _lastFetched;

	private static readonly string[] ServiceTypes = new string[4] { "WANIPConnection:2", "WANPPPConnection:2", "WANIPConnection:1", "WANPPPConnection:1" };

	internal UpnpSearcher(IIPAddressesProvider ipprovider)
	{
		_ipprovider = ipprovider;
		Sockets = CreateSockets();
		_devices = new Dictionary<Uri, NatDevice>();
		_lastFetched = new Dictionary<IPAddress, DateTime>();
	}

	private List<UdpClient> CreateSockets()
	{
		List<UdpClient> list = new List<UdpClient>();
		try
		{
			foreach (IPAddress item in _ipprovider.UnicastAddresses())
			{
				try
				{
					list.Add(new UdpClient(new IPEndPoint(item, 0)));
				}
				catch (Exception)
				{
				}
			}
		}
		catch (Exception)
		{
			list.Add(new UdpClient(0));
		}
		return list;
	}

	protected override void Discover(UdpClient client, CancellationToken cancelationToken)
	{
		NextSearch = DateTime.UtcNow.AddSeconds(1.0);
		IPEndPoint endPoint = new IPEndPoint(WellKnownConstants.IPv4MulticastAddress, 1900);
		string[] serviceTypes = ServiceTypes;
		for (int i = 0; i < serviceTypes.Length; i++)
		{
			string s = DiscoverDeviceMessage.Encode(serviceTypes[i]);
			byte[] bytes = Encoding.ASCII.GetBytes(s);
			for (int j = 0; j < 2; j = checked(j + 1))
			{
				if (cancelationToken.IsCancellationRequested)
				{
					return;
				}
				client.Send(bytes, bytes.Length, endPoint);
			}
		}
	}

	public override NatDevice AnalyseReceivedResponse(IPAddress localAddress, byte[] response, IPEndPoint endpoint)
	{
		string text = null;
		try
		{
			text = Encoding.UTF8.GetString(response);
			DiscoveryResponseMessage discoveryResponseMessage = new DiscoveryResponseMessage(text);
			string text2 = discoveryResponseMessage["ST"];
			if (!IsValidControllerService(text2))
			{
				NatDiscoverer.TraceSource.LogWarn("Invalid controller service. Ignoring.");
				return null;
			}
			NatDiscoverer.TraceSource.LogInfo("UPnP Response: Router advertised a '{0}' service!!!", text2);
			Uri uri = new Uri(discoveryResponseMessage["Location"] ?? discoveryResponseMessage["AL"]);
			NatDiscoverer.TraceSource.LogInfo("Found device at: {0}", uri.ToString());
			if (_devices.ContainsKey(uri))
			{
				NatDiscoverer.TraceSource.LogInfo("Already found - Ignored");
				_devices[uri].Touch();
				return null;
			}
			if (_lastFetched.ContainsKey(endpoint.Address))
			{
				DateTime dateTime = _lastFetched[endpoint.Address];
				if (DateTime.Now - dateTime < TimeSpan.FromSeconds(20.0))
				{
					return null;
				}
			}
			_lastFetched[endpoint.Address] = DateTime.Now;
			NatDiscoverer.TraceSource.LogInfo("{0}:{1}: Fetching service list", uri.Host, uri.Port);
			UpnpNatDeviceInfo deviceInfo = BuildUpnpNatDeviceInfo(localAddress, uri);
			UpnpNatDevice upnpNatDevice;
			lock (_devices)
			{
				upnpNatDevice = new UpnpNatDevice(deviceInfo);
				if (!_devices.ContainsKey(uri))
				{
					_devices.Add(uri, upnpNatDevice);
				}
			}
			return upnpNatDevice;
		}
		catch (Exception ex)
		{
			NatDiscoverer.TraceSource.LogError("Unhandled exception when trying to decode a device's response. ");
			NatDiscoverer.TraceSource.LogError("Report the issue in https://github.com/lontivero/Open.Nat/issues");
			NatDiscoverer.TraceSource.LogError("Also copy and paste the following info:");
			NatDiscoverer.TraceSource.LogError("-- beging ---------------------------------");
			NatDiscoverer.TraceSource.LogError(ex.Message);
			NatDiscoverer.TraceSource.LogError("Data string:");
			NatDiscoverer.TraceSource.LogError(text ?? "No data available");
			NatDiscoverer.TraceSource.LogError("-- end ------------------------------------");
		}
		return null;
	}

	private static bool IsValidControllerService(string serviceType)
	{
		return (from serviceName in ServiceTypes
			let serviceUrn = $"urn:schemas-upnp-org:service:{serviceName}"
			where serviceType.ContainsIgnoreCase(serviceUrn)
			select new
			{
				ServiceName = serviceName,
				ServiceUrn = serviceUrn
			}).Any();
	}

	private UpnpNatDeviceInfo BuildUpnpNatDeviceInfo(IPAddress localAddress, Uri location)
	{
		NatDiscoverer.TraceSource.LogInfo("Found device at: {0}", location.ToString());
		IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse(location.Host), location.Port);
		WebResponse webResponse = null;
		try
		{
			HttpWebRequest httpWebRequest = WebRequest.CreateHttp(location);
			httpWebRequest.Headers.Add("ACCEPT-LANGUAGE", "en");
			httpWebRequest.Method = "GET";
			webResponse = httpWebRequest.GetResponse();
			if (webResponse is HttpWebResponse httpWebResponse && httpWebResponse.StatusCode != HttpStatusCode.OK)
			{
				throw new Exception($"Couldn't get services list: {httpWebResponse.StatusCode} {httpWebResponse.StatusDescription}");
			}
			XmlDocument xmlDocument = ReadXmlResponse(webResponse);
			NatDiscoverer.TraceSource.LogInfo("{0}: Parsed services list", iPEndPoint);
			XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);
			xmlNamespaceManager.AddNamespace("ns", "urn:schemas-upnp-org:device-1-0");
			foreach (XmlNode item in xmlDocument.SelectNodes("//ns:service", xmlNamespaceManager))
			{
				string xmlElementText = item.GetXmlElementText("serviceType");
				if (IsValidControllerService(xmlElementText))
				{
					NatDiscoverer.TraceSource.LogInfo("{0}: Found service: {1}", iPEndPoint, xmlElementText);
					string xmlElementText2 = item.GetXmlElementText("controlURL");
					NatDiscoverer.TraceSource.LogInfo("{0}: Found upnp service at: {1}", iPEndPoint, xmlElementText2);
					NatDiscoverer.TraceSource.LogInfo("{0}: Handshake Complete", iPEndPoint);
					return new UpnpNatDeviceInfo(localAddress, location, xmlElementText2, xmlElementText);
				}
			}
			throw new Exception("No valid control service was found in the service descriptor document");
		}
		catch (WebException ex)
		{
			NatDiscoverer.TraceSource.LogError("{0}: Device denied the connection attempt: {1}", iPEndPoint, ex);
			if (ex.InnerException is SocketException ex2)
			{
				NatDiscoverer.TraceSource.LogError("{0}: ErrorCode:{1}", iPEndPoint, ex2.ErrorCode);
				NatDiscoverer.TraceSource.LogError("Go to http://msdn.microsoft.com/en-us/library/system.net.sockets.socketerror.aspx");
				NatDiscoverer.TraceSource.LogError("Usually this happens. Try resetting the device and try again. If you are in a VPN, disconnect and try again.");
			}
			throw;
		}
		finally
		{
			webResponse?.Close();
		}
	}

	private static XmlDocument ReadXmlResponse(WebResponse response)
	{
		using StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
		string xml = streamReader.ReadToEnd();
		XmlDocument xmlDocument = new XmlDocument();
		xmlDocument.LoadXml(xml);
		return xmlDocument;
	}
}
internal class DiscoveryResponseMessage
{
	private readonly IDictionary<string, string> _headers;

	public string this[string key] => _headers[key.ToUpperInvariant()];

	public DiscoveryResponseMessage(string message)
	{
		var source = from h in message.Split(new string[1] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Skip(1)
			let c = h.Split(new char[1] { ':' })
			let key = c[0]
			let value = (c.Length > 1) ? string.Join(":", c.Skip(1).ToArray()) : string.Empty
			select new
			{
				Key = key,
				Value = value.Trim()
			};
		_headers = source.ToDictionary(x => x.Key.ToUpperInvariant(), x => x.Value);
	}
}
internal static class DiscoverDeviceMessage
{
	public static string Encode(string serviceType)
	{
		return string.Format(CultureInfo.InvariantCulture, "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 3\r\nST: urn:schemas-upnp-org:service:{0}\r\n\r\n", new object[1] { serviceType });
	}
}
internal class CreatePortMappingRequestMessage : RequestMessageBase
{
	private readonly Mapping _mapping;

	public CreatePortMappingRequestMessage(Mapping mapping)
	{
		_mapping = mapping;
	}

	public override IDictionary<string, object> ToXml()
	{
		string value = (_mapping.PublicIP.Equals(IPAddress.None) ? string.Empty : _mapping.PublicIP.ToString());
		return new Dictionary<string, object>
		{
			{ "NewRemoteHost", value },
			{ "NewExternalPort", _mapping.PublicPort },
			{
				"NewProtocol",
				(_mapping.Protocol == Protocol.Tcp) ? "TCP" : "UDP"
			},
			{ "NewInternalPort", _mapping.PrivatePort },
			{ "NewInternalClient", _mapping.PrivateIP },
			{ "NewEnabled", 1 },
			{ "NewPortMappingDescription", _mapping.Description },
			{ "NewLeaseDuration", _mapping.Lifetime }
		};
	}
}
internal class DeletePortMappingRequestMessage : RequestMessageBase
{
	private readonly Mapping _mapping;

	public DeletePortMappingRequestMessage(Mapping mapping)
	{
		_mapping = mapping;
	}

	public override IDictionary<string, object> ToXml()
	{
		return new Dictionary<string, object>
		{
			{
				"NewRemoteHost",
				string.Empty
			},
			{ "NewExternalPort", _mapping.PublicPort },
			{
				"NewProtocol",
				(_mapping.Protocol == Protocol.Tcp) ? "TCP" : "UDP"
			}
		};
	}
}
internal class GetExternalIPAddressRequestMessage : RequestMessageBase
{
	public override IDictionary<string, object> ToXml()
	{
		return new Dictionary<string, object>();
	}
}
internal class GetGenericPortMappingEntry : RequestMessageBase
{
	private readonly int _index;

	public GetGenericPortMappingEntry(int index)
	{
		_index = index;
	}

	public override IDictionary<string, object> ToXml()
	{
		return new Dictionary<string, object> { { "NewPortMappingIndex", _index } };
	}
}
internal class GetSpecificPortMappingEntryRequestMessage : RequestMessageBase
{
	private readonly int _externalPort;

	private readonly Protocol _protocol;

	public GetSpecificPortMappingEntryRequestMessage(Protocol protocol, int externalPort)
	{
		_protocol = protocol;
		_externalPort = externalPort;
	}

	public override IDictionary<string, object> ToXml()
	{
		return new Dictionary<string, object>
		{
			{
				"NewRemoteHost",
				string.Empty
			},
			{ "NewExternalPort", _externalPort },
			{
				"NewProtocol",
				(_protocol == Protocol.Tcp) ? "TCP" : "UDP"
			}
		};
	}
}
internal abstract class ResponseMessageBase
{
	private readonly XmlDocument _document;

	protected string ServiceType;

	private readonly string _typeName;

	protected ResponseMessageBase(XmlDocument response, string serviceType, string typeName)
	{
		_document = response;
		ServiceType = serviceType;
		_typeName = typeName;
	}

	protected XmlNode GetNode()
	{
		XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(_document.NameTable);
		xmlNamespaceManager.AddNamespace("responseNs", ServiceType);
		string typeName = _typeName;
		string text = typeName.Substring(0, checked(typeName.Length - "Message".Length));
		return _document.SelectSingleNode("//responseNs:" + text, xmlNamespaceManager) ?? throw new InvalidOperationException("The response is invalid: " + text);
	}
}
internal class GetExternalIPAddressResponseMessage : ResponseMessageBase
{
	public IPAddress ExternalIPAddress { get; private set; }

	public GetExternalIPAddressResponseMessage(XmlDocument response, string serviceType)
		: base(response, serviceType, "GetExternalIPAddressResponseMessage")
	{
		string xmlElementText = GetNode().GetXmlElementText("NewExternalIPAddress");
		ExternalIPAddress = IPAddress.Parse(xmlElementText);
	}
}
internal class GetPortMappingEntryResponseMessage : ResponseMessageBase
{
	public string RemoteHost { get; private set; }

	public int ExternalPort { get; private set; }

	public Protocol Protocol { get; private set; }

	public int InternalPort { get; private set; }

	public string InternalClient { get; private set; }

	public bool Enabled { get; private set; }

	public string PortMappingDescription { get; private set; }

	public int LeaseDuration { get; private set; }

	internal GetPortMappingEntryResponseMessage(XmlDocument response, string serviceType, bool genericMapping)
		: base(response, serviceType, genericMapping ? "GetGenericPortMappingEntryResponseMessage" : "GetSpecificPortMappingEntryResponseMessage")
	{
		XmlNode node = GetNode();
		RemoteHost = (genericMapping ? node.GetXmlElementText("NewRemoteHost") : string.Empty);
		ExternalPort = (genericMapping ? Convert.ToInt32(node.GetXmlElementText("NewExternalPort")) : 65535);
		if (genericMapping)
		{
			Protocol = ((!node.GetXmlElementText("NewProtocol").Equals("TCP", StringComparison.InvariantCultureIgnoreCase)) ? Protocol.Udp : Protocol.Tcp);
		}
		else
		{
			Protocol = Protocol.Udp;
		}
		InternalPort = Convert.ToInt32(node.GetXmlElementText("NewInternalPort"));
		InternalClient = node.GetXmlElementText("NewInternalClient");
		Enabled = node.GetXmlElementText("NewEnabled") == "1";
		PortMappingDescription = node.GetXmlElementText("NewPortMappingDescription");
		LeaseDuration = Convert.ToInt32(node.GetXmlElementText("NewLeaseDuration"));
	}
}
internal abstract class RequestMessageBase
{
	public abstract IDictionary<string, object> ToXml();
}
internal class SoapClient
{
	private readonly string _serviceType;

	private readonly Uri _url;

	public SoapClient(Uri url, string serviceType)
	{
		_url = url;
		_serviceType = serviceType;
	}

	public async Task<XmlDocument> InvokeAsync(string operationName, IDictionary<string, object> args)
	{
		NatDiscoverer.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "SOAPACTION: **{0}** url:{1}", operationName, _url);
		byte[] messageBody = BuildMessageBody(operationName, args);
		HttpWebRequest request = BuildHttpWebRequest(operationName, messageBody);
		if (messageBody.Length != 0)
		{
			using Stream stream = await request.GetRequestStreamAsync();
			await stream.WriteAsync(messageBody, 0, messageBody.Length);
		}
		using WebResponse webResponse = await GetWebResponse(request);
		Stream responseStream = webResponse.GetResponseStream();
		long contentLength = webResponse.ContentLength;
		StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);
		string response = ((contentLength != -1) ? streamReader.ReadAsMany(checked((int)contentLength)) : streamReader.ReadToEnd());
		XmlDocument xmlDocument = GetXmlDocument(response);
		webResponse.Close();
		return xmlDocument;
	}

	private static async Task<WebResponse> GetWebResponse(WebRequest request)
	{
		WebResponse webResponse;
		try
		{
			webResponse = await request.GetResponseAsync();
		}
		catch (WebException ex)
		{
			NatDiscoverer.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "WebException status: {0}", ex.Status);
			webResponse = ex.Response as HttpWebResponse;
			if (webResponse == null)
			{
				throw;
			}
		}
		return webResponse;
	}

	private HttpWebRequest BuildHttpWebRequest(string operationName, byte[] messageBody)
	{
		HttpWebRequest httpWebRequest = WebRequest.CreateHttp(_url);
		httpWebRequest.KeepAlive = false;
		httpWebRequest.Method = "POST";
		httpWebRequest.ContentType = "text/xml; charset=\"utf-8\"";
		httpWebRequest.Headers.Add("SOAPACTION", "\"" + _serviceType + "#" + operationName + "\"");
		httpWebRequest.ContentLength = messageBody.Length;
		return httpWebRequest;
	}

	private byte[] BuildMessageBody(string operationName, IEnumerable<KeyValuePair<string, object>> args)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("<s:Envelope ");
		stringBuilder.AppendLine("   xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" ");
		stringBuilder.AppendLine("   s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">");
		stringBuilder.AppendLine("   <s:Body>");
		stringBuilder.AppendLine("\t  <u:" + operationName + " xmlns:u=\"" + _serviceType + "\">");
		foreach (KeyValuePair<string, object> arg in args)
		{
			stringBuilder.AppendLine("\t\t <" + arg.Key + ">" + Convert.ToString(arg.Value, CultureInfo.InvariantCulture) + "</" + arg.Key + ">");
		}
		stringBuilder.AppendLine("\t  </u:" + operationName + ">");
		stringBuilder.AppendLine("   </s:Body>");
		stringBuilder.Append("</s:Envelope>\r\n\r\n");
		string s = stringBuilder.ToString();
		return Encoding.UTF8.GetBytes(s);
	}

	private XmlDocument GetXmlDocument(string response)
	{
		XmlDocument xmlDocument = new XmlDocument();
		xmlDocument.LoadXml(response);
		XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);
		xmlNamespaceManager.AddNamespace("errorNs", "urn:schemas-upnp-org:control-1-0");
		XmlNode node;
		if ((node = xmlDocument.SelectSingleNode("//errorNs:UPnPError", xmlNamespaceManager)) != null)
		{
			int num = Convert.ToInt32(node.GetXmlElementText("errorCode"), CultureInfo.InvariantCulture);
			string xmlElementText = node.GetXmlElementText("errorDescription");
			NatDiscoverer.TraceSource.LogWarn("Server failed with error: {0} - {1}", num, xmlElementText);
			throw new MappingException(num, xmlElementText);
		}
		return xmlDocument;
	}
}
internal static class UpnpConstants
{
	public const int InvalidArguments = 402;

	public const int ActionFailed = 501;

	public const int Unathorized = 606;

	public const int SpecifiedArrayIndexInvalid = 713;

	public const int NoSuchEntryInArray = 714;

	public const int WildCardNotPermittedInSourceIp = 715;

	public const int WildCardNotPermittedInExternalPort = 716;

	public const int ConflictInMappingEntry = 718;

	public const int SamePortValuesRequired = 724;

	public const int OnlyPermanentLeasesSupported = 725;

	public const int RemoteHostOnlySupportsWildcard = 726;

	public const int ExternalPortOnlySupportsWildcard = 727;

	public const int NoPortMapsAvailable = 728;

	public const int ConflictWithOtherMechanisms = 729;

	public const int WildCardNotPermittedInIntPort = 732;
}
internal class UpnpNatDeviceInfo
{
	public IPEndPoint HostEndPoint { get; private set; }

	public IPAddress LocalAddress { get; private set; }

	public string ServiceType { get; private set; }

	public Uri ServiceControlUri { get; private set; }

	public UpnpNatDeviceInfo(IPAddress localAddress, Uri locationUri, string serviceControlUrl, string serviceType)
	{
		LocalAddress = localAddress;
		ServiceType = serviceType;
		HostEndPoint = new IPEndPoint(IPAddress.Parse(locationUri.Host), locationUri.Port);
		if (Uri.IsWellFormedUriString(serviceControlUrl, UriKind.Absolute))
		{
			Uri uri = new Uri(serviceControlUrl);
			IPEndPoint hostEndPoint = HostEndPoint;
			serviceControlUrl = uri.PathAndQuery;
			NatDiscoverer.TraceSource.LogInfo("{0}: Absolute URI detected. Host address is now: {1}", hostEndPoint, HostEndPoint);
			NatDiscoverer.TraceSource.LogInfo("{0}: New control url: {1}", HostEndPoint, serviceControlUrl);
		}
		UriBuilder uriBuilder = new UriBuilder("http", locationUri.Host, locationUri.Port);
		ServiceControlUri = new Uri(uriBuilder.Uri, serviceControlUrl);
	}
}
internal sealed class UpnpNatDevice : NatDevice
{
	internal readonly UpnpNatDeviceInfo DeviceInfo;

	private readonly SoapClient _soapClient;

	internal UpnpNatDevice(UpnpNatDeviceInfo deviceInfo)
	{
		Touch();
		DeviceInfo = deviceInfo;
		_soapClient = new SoapClient(DeviceInfo.ServiceControlUri, DeviceInfo.ServiceType);
	}

	public override async Task<IPAddress> GetExternalIPAsync()
	{
		NatDiscoverer.TraceSource.LogInfo("GetExternalIPAsync - Getting external IP address");
		GetExternalIPAddressRequestMessage getExternalIPAddressRequestMessage = new GetExternalIPAddressRequestMessage();
		return new GetExternalIPAddressResponseMessage(await _soapClient.InvokeAsync("GetExternalIPAddress", getExternalIPAddressRequestMessage.ToXml()).TimeoutAfter(TimeSpan.FromSeconds(4.0)), DeviceInfo.ServiceType).ExternalIPAddress;
	}

	public override async Task CreatePortMapAsync(Mapping mapping)
	{
		Guard.IsNotNull(mapping, "mapping");
		if (mapping.PrivateIP.Equals(IPAddress.None))
		{
			mapping.PrivateIP = DeviceInfo.LocalAddress;
		}
		NatDiscoverer.TraceSource.LogInfo("CreatePortMapAsync - Creating port mapping {0}", mapping);
		bool retry = false;
		try
		{
			CreatePortMappingRequestMessage createPortMappingRequestMessage = new CreatePortMappingRequestMessage(mapping);
			await _soapClient.InvokeAsync("AddPortMapping", createPortMappingRequestMessage.ToXml()).TimeoutAfter(TimeSpan.FromSeconds(4.0));
			RegisterMapping(mapping);
		}
		catch (MappingException ex)
		{
			switch (ex.ErrorCode)
			{
			case 725:
				NatDiscoverer.TraceSource.LogWarn("Only Permanent Leases Supported - There is no warranty it will be closed");
				mapping.Lifetime = 0;
				mapping.LifetimeType = MappingLifetime.ForcedSession;
				retry = true;
				break;
			case 724:
				NatDiscoverer.TraceSource.LogWarn("Same Port Values Required - Using internal port {0}", mapping.PrivatePort);
				mapping.PublicPort = mapping.PrivatePort;
				retry = true;
				break;
			case 726:
				NatDiscoverer.TraceSource.LogWarn("Remote Host Only Supports Wildcard");
				mapping.PublicIP = IPAddress.None;
				retry = true;
				break;
			case 727:
				NatDiscoverer.TraceSource.LogWarn("External Port Only Supports Wildcard");
				throw;
			case 718:
				NatDiscoverer.TraceSource.LogWarn("Conflict with an already existing mapping");
				throw;
			default:
				throw;
			}
		}
		if (retry)
		{
			await CreatePortMapAsync(mapping);
		}
	}

	public override async Task DeletePortMapAsync(Mapping mapping)
	{
		Guard.IsNotNull(mapping, "mapping");
		if (mapping.PrivateIP.Equals(IPAddress.None))
		{
			mapping.PrivateIP = DeviceInfo.LocalAddress;
		}
		NatDiscoverer.TraceSource.LogInfo("DeletePortMapAsync - Deleteing port mapping {0}", mapping);
		try
		{
			DeletePortMappingRequestMessage deletePortMappingRequestMessage = new DeletePortMappingRequestMessage(mapping);
			await _soapClient.InvokeAsync("DeletePortMapping", deletePortMappingRequestMessage.ToXml()).TimeoutAfter(TimeSpan.FromSeconds(4.0));
			UnregisterMapping(mapping);
		}
		catch (MappingException ex)
		{
			if (ex.ErrorCode != 714)
			{
				throw;
			}
		}
	}

	public override async Task<IEnumerable<Mapping>> GetAllMappingsAsync()
	{
		int index = 0;
		List<Mapping> mappings = new List<Mapping>();
		NatDiscoverer.TraceSource.LogInfo("GetAllMappingsAsync - Getting all mappings");
		while (true)
		{
			try
			{
				GetGenericPortMappingEntry getGenericPortMappingEntry = new GetGenericPortMappingEntry(checked(index++));
				GetPortMappingEntryResponseMessage getPortMappingEntryResponseMessage = new GetPortMappingEntryResponseMessage(await _soapClient.InvokeAsync("GetGenericPortMappingEntry", getGenericPortMappingEntry.ToXml()).TimeoutAfter(TimeSpan.FromSeconds(4.0)), DeviceInfo.ServiceType, genericMapping: true);
				if (!IPAddress.TryParse(getPortMappingEntryResponseMessage.InternalClient, out IPAddress address))
				{
					NatDiscoverer.TraceSource.LogWarn("InternalClient is not an IP address. Mapping ignored!");
					continue;
				}
				Mapping item = new Mapping(getPortMappingEntryResponseMessage.Protocol, address, getPortMappingEntryResponseMessage.InternalPort, getPortMappingEntryResponseMessage.ExternalPort, getPortMappingEntryResponseMessage.LeaseDuration, getPortMappingEntryResponseMessage.PortMappingDescription);
				mappings.Add(item);
			}
			catch (MappingException ex)
			{
				if (ex.ErrorCode == 713 || ex.ErrorCode == 714 || ex.ErrorCode == 402 || ex.ErrorCode == 501)
				{
					NatDiscoverer.TraceSource.LogWarn("Router failed with {0}-{1}. No more mappings is assumed.", ex.ErrorCode, ex.ErrorText);
					break;
				}
				throw;
			}
		}
		return mappings.ToArray();
	}

	public override async Task<Mapping> GetSpecificMappingAsync(Protocol protocol, int publicPort)
	{
		Guard.IsTrue(protocol == Protocol.Tcp || protocol == Protocol.Udp, "protocol");
		Guard.IsInRange(publicPort, 0, 65535, "port");
		NatDiscoverer.TraceSource.LogInfo("GetSpecificMappingAsync - Getting mapping for protocol: {0} port: {1}", Enum.GetName(typeof(Protocol), protocol), publicPort);
		try
		{
			GetSpecificPortMappingEntryRequestMessage getSpecificPortMappingEntryRequestMessage = new GetSpecificPortMappingEntryRequestMessage(protocol, publicPort);
			GetPortMappingEntryResponseMessage getPortMappingEntryResponseMessage = new GetPortMappingEntryResponseMessage(await _soapClient.InvokeAsync("GetSpecificPortMappingEntry", getSpecificPortMappingEntryRequestMessage.ToXml()).TimeoutAfter(TimeSpan.FromSeconds(4.0)), DeviceInfo.ServiceType, genericMapping: false);
			if (getPortMappingEntryResponseMessage.Protocol != protocol)
			{
				NatDiscoverer.TraceSource.LogWarn("Router responded to a protocol {0} query with a protocol {1} answer, work around applied.", protocol, getPortMappingEntryResponseMessage.Protocol);
			}
			return new Mapping(protocol, IPAddress.Parse(getPortMappingEntryResponseMessage.InternalClient), getPortMappingEntryResponseMessage.InternalPort, publicPort, getPortMappingEntryResponseMessage.LeaseDuration, getPortMappingEntryResponseMessage.PortMappingDescription);
		}
		catch (MappingException ex)
		{
			if (ex.ErrorCode == 713 || ex.ErrorCode == 714 || ex.ErrorCode == 402 || ex.ErrorCode == 501)
			{
				NatDiscoverer.TraceSource.LogWarn("Router failed with {0}-{1}. No more mappings is assumed.", ex.ErrorCode, ex.ErrorText);
				return null;
			}
			throw;
		}
	}

	public override string ToString()
	{
		return $"EndPoint: {DeviceInfo.HostEndPoint}\nControl Url: {DeviceInfo.ServiceControlUri}\nService Type: {DeviceInfo.ServiceType}\nLast Seen: {base.LastSeen}";
	}
}
internal static class StreamExtensions
{
	internal static string ReadAsMany(this StreamReader stream, int bytesToRead)
	{
		char[] array = new char[bytesToRead];
		stream.ReadBlock(array, 0, bytesToRead);
		return new string(array);
	}

	internal static string GetXmlElementText(this XmlNode node, string elementName)
	{
		XmlElement xmlElement = node[elementName];
		if (xmlElement == null)
		{
			return string.Empty;
		}
		return xmlElement.InnerText;
	}

	internal static bool ContainsIgnoreCase(this string s, string pattern)
	{
		return s.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) >= 0;
	}

	internal static void LogInfo(this TraceSource source, string format, params object[] args)
	{
		source.TraceEvent(TraceEventType.Information, 0, format, args);
	}

	internal static void LogWarn(this TraceSource source, string format, params object[] args)
	{
		source.TraceEvent(TraceEventType.Warning, 0, format, args);
	}

	internal static void LogError(this TraceSource source, string format, params object[] args)
	{
		source.TraceEvent(TraceEventType.Error, 0, format, args);
	}

	internal static string ToPrintableXml(this XmlDocument document)
	{
		using MemoryStream memoryStream = new MemoryStream();
		using XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.Unicode);
		try
		{
			xmlTextWriter.Formatting = Formatting.Indented;
			document.WriteContentTo(xmlTextWriter);
			xmlTextWriter.Flush();
			memoryStream.Flush();
			memoryStream.Position = 0L;
			return new StreamReader(memoryStream).ReadToEnd();
		}
		catch (Exception)
		{
			return document.ToString();
		}
	}

	public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan timeout)
	{
		CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource();
		if (await Task.WhenAny(new Task[2]
		{
			task,
			Task.Delay(timeout, timeoutCancellationTokenSource.Token)
		}) == task)
		{
			timeoutCancellationTokenSource.Cancel();
			return await task;
		}
		throw new TimeoutException("The operation has timed out. The network is broken, router has gone or is too busy.");
	}
}
internal interface IIPAddressesProvider
{
	IEnumerable<IPAddress> DnsAddresses();

	IEnumerable<IPAddress> GatewayAddresses();

	IEnumerable<IPAddress> UnicastAddresses();
}
internal class IPAddressesProvider : IIPAddressesProvider
{
	public IEnumerable<IPAddress> UnicastAddresses()
	{
		return IPAddresses((IPInterfaceProperties p) => p.UnicastAddresses.Select((UnicastIPAddressInformation x) => x.Address));
	}

	public IEnumerable<IPAddress> DnsAddresses()
	{
		return IPAddresses((IPInterfaceProperties p) => p.DnsAddresses);
	}

	public IEnumerable<IPAddress> GatewayAddresses()
	{
		return IPAddresses((IPInterfaceProperties p) => p.GatewayAddresses.Select((GatewayIPAddressInformation x) => x.Address));
	}

	private static IEnumerable<IPAddress> IPAddresses(Func<IPInterfaceProperties, IEnumerable<IPAddress>> ipExtractor)
	{
		return from networkInterface in NetworkInterface.GetAllNetworkInterfaces()
			where networkInterface.OperationalStatus == OperationalStatus.Up || networkInterface.OperationalStatus == OperationalStatus.Unknown
			let properties = networkInterface.GetIPProperties()
			from address in ipExtractor(properties)
			where address.AddressFamily == AddressFamily.InterNetwork
			select address;
	}
}
internal static class WellKnownConstants
{
	public static IPAddress IPv4MulticastAddress = IPAddress.Parse("239.255.255.250");

	public static IPEndPoint NatPmpEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 5351);
}

System.Buffers.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using FxResources.System.Buffers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Buffers")]
[assembly: AssemblyDescription("System.Buffers")]
[assembly: AssemblyDefaultAlias("System.Buffers")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.28619.01")]
[assembly: AssemblyInformationalVersion("4.6.28619.01 @BuiltBy: dlab14-DDVSOWINAGE069 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/7601f4f6225089ffb291dc7d58293c7bbf5c5d4f")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.3.0")]
[module: UnverifiableCode]
namespace FxResources.System.Buffers
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static Type ResourceType { get; } = typeof(SR);


		internal static string ArgumentException_BufferNotFromPool => GetResourceString("ArgumentException_BufferNotFromPool", null);

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}
	}
}
namespace System.Buffers
{
	public abstract class ArrayPool<T>
	{
		private static ArrayPool<T> s_sharedInstance;

		public static ArrayPool<T> Shared
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return Volatile.Read(ref s_sharedInstance) ?? EnsureSharedCreated();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ArrayPool<T> EnsureSharedCreated()
		{
			Interlocked.CompareExchange(ref s_sharedInstance, Create(), null);
			return s_sharedInstance;
		}

		public static ArrayPool<T> Create()
		{
			return new DefaultArrayPool<T>();
		}

		public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket)
		{
			return new DefaultArrayPool<T>(maxArrayLength, maxArraysPerBucket);
		}

		public abstract T[] Rent(int minimumLength);

		public abstract void Return(T[] array, bool clearArray = false);
	}
	[EventSource(Name = "System.Buffers.ArrayPoolEventSource")]
	internal sealed class ArrayPoolEventSource : EventSource
	{
		internal enum BufferAllocatedReason
		{
			Pooled,
			OverMaximumSize,
			PoolExhausted
		}

		internal static readonly System.Buffers.ArrayPoolEventSource Log = new System.Buffers.ArrayPoolEventSource();

		[Event(1, Level = EventLevel.Verbose)]
		internal unsafe void BufferRented(int bufferId, int bufferSize, int poolId, int bucketId)
		{
			EventData* ptr = stackalloc EventData[4];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			WriteEventCore(1, 4, ptr);
		}

		[Event(2, Level = EventLevel.Informational)]
		internal unsafe void BufferAllocated(int bufferId, int bufferSize, int poolId, int bucketId, BufferAllocatedReason reason)
		{
			EventData* ptr = stackalloc EventData[5];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			ptr[4] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&reason)
			};
			WriteEventCore(2, 5, ptr);
		}

		[Event(3, Level = EventLevel.Verbose)]
		internal void BufferReturned(int bufferId, int bufferSize, int poolId)
		{
			WriteEvent(3, bufferId, bufferSize, poolId);
		}
	}
	internal sealed class DefaultArrayPool<T> : ArrayPool<T>
	{
		private sealed class Bucket
		{
			internal readonly int _bufferLength;

			private readonly T[][] _buffers;

			private readonly int _poolId;

			private SpinLock _lock;

			private int _index;

			internal int Id => GetHashCode();

			internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
			{
				_lock = new SpinLock(Debugger.IsAttached);
				_buffers = new T[numberOfBuffers][];
				_bufferLength = bufferLength;
				_poolId = poolId;
			}

			internal T[] Rent()
			{
				T[][] buffers = _buffers;
				T[] array = null;
				bool lockTaken = false;
				bool flag = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index < buffers.Length)
					{
						array = buffers[_index];
						buffers[_index++] = null;
						flag = array == null;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
				if (flag)
				{
					array = new T[_bufferLength];
					System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
					if (log.IsEnabled())
					{
						log.BufferAllocated(array.GetHashCode(), _bufferLength, _poolId, Id, System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.Pooled);
					}
				}
				return array;
			}

			internal void Return(T[] array)
			{
				if (array.Length != _bufferLength)
				{
					throw new ArgumentException(System.SR.ArgumentException_BufferNotFromPool, "array");
				}
				bool lockTaken = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index != 0)
					{
						_buffers[--_index] = array;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
			}
		}

		private const int DefaultMaxArrayLength = 1048576;

		private const int DefaultMaxNumberOfArraysPerBucket = 50;

		private static T[] s_emptyArray;

		private readonly Bucket[] _buckets;

		private int Id => GetHashCode();

		internal DefaultArrayPool()
			: this(1048576, 50)
		{
		}

		internal DefaultArrayPool(int maxArrayLength, int maxArraysPerBucket)
		{
			if (maxArrayLength <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArrayLength");
			}
			if (maxArraysPerBucket <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArraysPerBucket");
			}
			if (maxArrayLength > 1073741824)
			{
				maxArrayLength = 1073741824;
			}
			else if (maxArrayLength < 16)
			{
				maxArrayLength = 16;
			}
			int id = Id;
			int num = System.Buffers.Utilities.SelectBucketIndex(maxArrayLength);
			Bucket[] array = new Bucket[num + 1];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new Bucket(System.Buffers.Utilities.GetMaxSizeForBucket(i), maxArraysPerBucket, id);
			}
			_buckets = array;
		}

		public override T[] Rent(int minimumLength)
		{
			if (minimumLength < 0)
			{
				throw new ArgumentOutOfRangeException("minimumLength");
			}
			if (minimumLength == 0)
			{
				return s_emptyArray ?? (s_emptyArray = new T[0]);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			T[] array = null;
			int num = System.Buffers.Utilities.SelectBucketIndex(minimumLength);
			if (num < _buckets.Length)
			{
				int num2 = num;
				do
				{
					array = _buckets[num2].Rent();
					if (array != null)
					{
						if (log.IsEnabled())
						{
							log.BufferRented(array.GetHashCode(), array.Length, Id, _buckets[num2].Id);
						}
						return array;
					}
				}
				while (++num2 < _buckets.Length && num2 != num + 2);
				array = new T[_buckets[num]._bufferLength];
			}
			else
			{
				array = new T[minimumLength];
			}
			if (log.IsEnabled())
			{
				int hashCode = array.GetHashCode();
				int bucketId = -1;
				log.BufferRented(hashCode, array.Length, Id, bucketId);
				log.BufferAllocated(hashCode, array.Length, Id, bucketId, (num >= _buckets.Length) ? System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.OverMaximumSize : System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.PoolExhausted);
			}
			return array;
		}

		public override void Return(T[] array, bool clearArray = false)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (array.Length == 0)
			{
				return;
			}
			int num = System.Buffers.Utilities.SelectBucketIndex(array.Length);
			if (num < _buckets.Length)
			{
				if (clearArray)
				{
					Array.Clear(array, 0, array.Length);
				}
				_buckets[num].Return(array);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			if (log.IsEnabled())
			{
				log.BufferReturned(array.GetHashCode(), array.Length, Id);
			}
		}
	}
	internal static class Utilities
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int SelectBucketIndex(int bufferSize)
		{
			uint num = (uint)(bufferSize - 1) >> 4;
			int num2 = 0;
			if (num > 65535)
			{
				num >>= 16;
				num2 = 16;
			}
			if (num > 255)
			{
				num >>= 8;
				num2 += 8;
			}
			if (num > 15)
			{
				num >>= 4;
				num2 += 4;
			}
			if (num > 3)
			{
				num >>= 2;
				num2 += 2;
			}
			if (num > 1)
			{
				num >>= 1;
				num2++;
			}
			return num2 + (int)num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int GetMaxSizeForBucket(int binIndex)
		{
			return 16 << binIndex;
		}
	}
}

System.IO.Pipelines.dll

Decompiled 2 weeks ago
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Sources;
using FxResources.System.IO.Pipelines;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("System.IO.Pipelines.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b86c4cb78549b34bab61a3b1800e23bfeb5b3ec390074041536a7e3cbd97f5f04cf0f857155a8928eaa29ebfd11cfbbad3ba70efea7bda3226c6a8d370a4cd303f714486b6ebc225985a638471e6ef571cc92a4613c00b8fa65d61ccee0cbe5f36330c9a01f4183559f1bef24cc2917c6d913e3a541333a1d05d9bed22b38cb")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.1", FrameworkDisplayName = ".NET Framework 4.6.1")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyDefaultAlias("System.IO.Pipelines")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("System.IO.Pipelines")]
[assembly: AssemblyFileVersion("5.0.1522.11506")]
[assembly: AssemblyInformationalVersion("5.0.15+3065735be79d6b7d17e8e3a723115810b43c9b3a")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("System.IO.Pipelines")]
[assembly: AssemblyMetadata("RepositoryUrl", "git://github.com/dotnet/runtime")]
[assembly: AssemblyVersion("5.0.0.2")]
[module: System.Runtime.CompilerServices.NullablePublicOnly(true)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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 NullablePublicOnlyAttribute : Attribute
	{
		public readonly bool IncludesInternals;

		public NullablePublicOnlyAttribute(bool P_0)
		{
			IncludesInternals = P_0;
		}
	}
}
namespace FxResources.System.IO.Pipelines
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled;

		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR)));

		internal static string AdvanceToInvalidCursor => GetResourceString("AdvanceToInvalidCursor");

		internal static string ConcurrentOperationsNotSupported => GetResourceString("ConcurrentOperationsNotSupported");

		internal static string FlushCanceledOnPipeWriter => GetResourceString("FlushCanceledOnPipeWriter");

		internal static string GetResultBeforeCompleted => GetResourceString("GetResultBeforeCompleted");

		internal static string InvalidExaminedOrConsumedPosition => GetResourceString("InvalidExaminedOrConsumedPosition");

		internal static string InvalidExaminedPosition => GetResourceString("InvalidExaminedPosition");

		internal static string InvalidZeroByteRead => GetResourceString("InvalidZeroByteRead");

		internal static string NoReadingOperationToComplete => GetResourceString("NoReadingOperationToComplete");

		internal static string ReadCanceledOnPipeReader => GetResourceString("ReadCanceledOnPipeReader");

		internal static string ReaderAndWriterHasToBeCompleted => GetResourceString("ReaderAndWriterHasToBeCompleted");

		internal static string ReadingAfterCompleted => GetResourceString("ReadingAfterCompleted");

		internal static string ReadingIsInProgress => GetResourceString("ReadingIsInProgress");

		internal static string WritingAfterCompleted => GetResourceString("WritingAfterCompleted");

		private static bool UsingResourceKeys()
		{
			return s_usingResourceKeys;
		}

		internal static string GetResourceString(string resourceKey, string? defaultString = null)
		{
			if (UsingResourceKeys())
			{
				return defaultString ?? resourceKey;
			}
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class DisallowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public MaybeNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
	internal sealed class NotNullIfNotNullAttribute : Attribute
	{
		public string ParameterName { get; }

		public NotNullIfNotNullAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	internal sealed class DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	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)]
	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;
		}
	}
}
namespace System.IO.Pipelines
{
	internal sealed class BufferSegment : ReadOnlySequenceSegment<byte>
	{
		private IMemoryOwner<byte> _memoryOwner;

		private byte[] _array;

		private BufferSegment _next;

		private int _end;

		public int End
		{
			get
			{
				return _end;
			}
			set
			{
				_end = value;
				base.Memory = AvailableMemory.Slice(0, value);
			}
		}

		public BufferSegment? NextSegment
		{
			get
			{
				return _next;
			}
			set
			{
				base.Next = value;
				_next = value;
			}
		}

		internal object? MemoryOwner => ((object)_memoryOwner) ?? ((object)_array);

		public Memory<byte> AvailableMemory { get; private set; }

		public int Length => End;

		public int WritableBytes
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return AvailableMemory.Length - End;
			}
		}

		public void SetOwnedMemory(IMemoryOwner<byte> memoryOwner)
		{
			_memoryOwner = memoryOwner;
			AvailableMemory = memoryOwner.Memory;
		}

		public void SetOwnedMemory(byte[] arrayPoolBuffer)
		{
			_array = arrayPoolBuffer;
			AvailableMemory = arrayPoolBuffer;
		}

		public void ResetMemory()
		{
			IMemoryOwner<byte> memoryOwner = _memoryOwner;
			if (memoryOwner != null)
			{
				_memoryOwner = null;
				memoryOwner.Dispose();
			}
			else
			{
				ArrayPool<byte>.Shared.Return(_array);
				_array = null;
			}
			base.Next = null;
			base.RunningIndex = 0L;
			base.Memory = default(ReadOnlyMemory<byte>);
			_next = null;
			_end = 0;
			AvailableMemory = default(Memory<byte>);
		}

		public void SetNext(BufferSegment segment)
		{
			NextSegment = segment;
			segment = this;
			while (((ReadOnlySequenceSegment<byte>)segment).Next != null)
			{
				((ReadOnlySequenceSegment<byte>)segment.NextSegment).RunningIndex = ((ReadOnlySequenceSegment<byte>)segment).RunningIndex + segment.Length;
				segment = segment.NextSegment;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static long GetLength(BufferSegment startSegment, int startIndex, BufferSegment endSegment, int endIndex)
		{
			return ((ReadOnlySequenceSegment<byte>)endSegment).RunningIndex + (uint)endIndex - (((ReadOnlySequenceSegment<byte>)startSegment).RunningIndex + (uint)startIndex);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static long GetLength(long startPosition, BufferSegment endSegment, int endIndex)
		{
			return ((ReadOnlySequenceSegment<byte>)endSegment).RunningIndex + (uint)endIndex - startPosition;
		}
	}
	internal readonly struct CompletionData
	{
		public Action<object?> Completion { get; }

		public object? CompletionState { get; }

		public ExecutionContext? ExecutionContext { get; }

		public SynchronizationContext? SynchronizationContext { get; }

		public CompletionData(Action<object?> completion, object? completionState, ExecutionContext? executionContext, SynchronizationContext? synchronizationContext)
		{
			Completion = completion;
			CompletionState = completionState;
			ExecutionContext = executionContext;
			SynchronizationContext = synchronizationContext;
		}
	}
	public struct FlushResult
	{
		internal ResultFlags _resultFlags;

		public bool IsCanceled => (_resultFlags & ResultFlags.Canceled) != 0;

		public bool IsCompleted => (_resultFlags & ResultFlags.Completed) != 0;

		public FlushResult(bool isCanceled, bool isCompleted)
		{
			_resultFlags = ResultFlags.None;
			if (isCanceled)
			{
				_resultFlags |= ResultFlags.Canceled;
			}
			if (isCompleted)
			{
				_resultFlags |= ResultFlags.Completed;
			}
		}
	}
	internal sealed class InlineScheduler : PipeScheduler
	{
		public override void Schedule(Action<object?> action, object? state)
		{
			action(state);
		}

		internal override void UnsafeSchedule(Action<object?> action, object? state)
		{
			action(state);
		}
	}
	public interface IDuplexPipe
	{
		PipeReader Input { get; }

		PipeWriter Output { get; }
	}
	internal struct BufferSegmentStack
	{
		private readonly struct SegmentAsValueType
		{
			private readonly BufferSegment _value;

			private SegmentAsValueType(BufferSegment value)
			{
				_value = value;
			}

			public static implicit operator SegmentAsValueType(BufferSegment s)
			{
				return new SegmentAsValueType(s);
			}

			public static implicit operator BufferSegment(SegmentAsValueType s)
			{
				return s._value;
			}
		}

		private SegmentAsValueType[] _array;

		private int _size;

		public int Count => _size;

		public BufferSegmentStack(int size)
		{
			_array = new SegmentAsValueType[size];
			_size = 0;
		}

		public bool TryPop([NotNullWhen(true)] out BufferSegment? result)
		{
			int num = _size - 1;
			SegmentAsValueType[] array = _array;
			if ((uint)num >= (uint)array.Length)
			{
				result = null;
				return false;
			}
			_size = num;
			result = array[num];
			array[num] = default(SegmentAsValueType);
			return true;
		}

		public void Push(BufferSegment item)
		{
			int size = _size;
			SegmentAsValueType[] array = _array;
			if ((uint)size < (uint)array.Length)
			{
				array[size] = item;
				_size = size + 1;
			}
			else
			{
				PushWithResize(item);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void PushWithResize(BufferSegment item)
		{
			Array.Resize(ref _array, 2 * _array.Length);
			_array[_size] = item;
			_size++;
		}
	}
	public sealed class Pipe
	{
		private sealed class DefaultPipeReader : PipeReader, IValueTaskSource<ReadResult>
		{
			private readonly Pipe _pipe;

			public DefaultPipeReader(Pipe pipe)
			{
				_pipe = pipe;
			}

			public override bool TryRead(out ReadResult result)
			{
				return _pipe.TryRead(out result);
			}

			public override ValueTask<ReadResult> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
			{
				return _pipe.ReadAsync(cancellationToken);
			}

			public override void AdvanceTo(SequencePosition consumed)
			{
				_pipe.AdvanceReader(in consumed);
			}

			public override void AdvanceTo(SequencePosition consumed, SequencePosition examined)
			{
				_pipe.AdvanceReader(in consumed, in examined);
			}

			public override void CancelPendingRead()
			{
				_pipe.CancelPendingRead();
			}

			public override void Complete(Exception exception = null)
			{
				_pipe.CompleteReader(exception);
			}

			public override void OnWriterCompleted(Action<Exception, object> callback, object state)
			{
				_pipe.OnWriterCompleted(callback, state);
			}

			public ValueTaskSourceStatus GetStatus(short token)
			{
				return _pipe.GetReadAsyncStatus();
			}

			public ReadResult GetResult(short token)
			{
				return _pipe.GetReadAsyncResult();
			}

			public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
			{
				_pipe.OnReadAsyncCompleted(continuation, state, flags);
			}
		}

		private sealed class DefaultPipeWriter : PipeWriter, IValueTaskSource<FlushResult>
		{
			private readonly Pipe _pipe;

			public DefaultPipeWriter(Pipe pipe)
			{
				_pipe = pipe;
			}

			public override void Complete(Exception exception = null)
			{
				_pipe.CompleteWriter(exception);
			}

			public override void CancelPendingFlush()
			{
				_pipe.CancelPendingFlush();
			}

			public override void OnReaderCompleted(Action<Exception, object> callback, object state)
			{
				_pipe.OnReaderCompleted(callback, state);
			}

			public override ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
			{
				return _pipe.FlushAsync(cancellationToken);
			}

			public override void Advance(int bytes)
			{
				_pipe.Advance(bytes);
			}

			public override Memory<byte> GetMemory(int sizeHint = 0)
			{
				return _pipe.GetMemory(sizeHint);
			}

			public override Span<byte> GetSpan(int sizeHint = 0)
			{
				return _pipe.GetSpan(sizeHint);
			}

			public ValueTaskSourceStatus GetStatus(short token)
			{
				return _pipe.GetFlushAsyncStatus();
			}

			public FlushResult GetResult(short token)
			{
				return _pipe.GetFlushAsyncResult();
			}

			public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
			{
				_pipe.OnFlushAsyncCompleted(continuation, state, flags);
			}

			public override ValueTask<FlushResult> WriteAsync(ReadOnlyMemory<byte> source, CancellationToken cancellationToken = default(CancellationToken))
			{
				return _pipe.WriteAsync(source, cancellationToken);
			}
		}

		internal const int InitialSegmentPoolSize = 16;

		internal const int MaxSegmentPoolSize = 256;

		private static readonly Action<object> s_signalReaderAwaitable = delegate(object state)
		{
			((Pipe)state).ReaderCancellationRequested();
		};

		private static readonly Action<object> s_signalWriterAwaitable = delegate(object state)
		{
			((Pipe)state).WriterCancellationRequested();
		};

		private static readonly Action<object> s_invokeCompletionCallbacks = delegate(object state)
		{
			((PipeCompletionCallbacks)state).Execute();
		};

		private static readonly ContextCallback s_executionContextRawCallback = ExecuteWithoutExecutionContext;

		private static readonly SendOrPostCallback s_syncContextExecutionContextCallback = ExecuteWithExecutionContext;

		private static readonly SendOrPostCallback s_syncContextExecuteWithoutExecutionContextCallback = ExecuteWithoutExecutionContext;

		private static readonly Action<object> s_scheduleWithExecutionContextCallback = ExecuteWithExecutionContext;

		private readonly object _sync = new object();

		private readonly MemoryPool<byte> _pool;

		private readonly int _minimumSegmentSize;

		private readonly long _pauseWriterThreshold;

		private readonly long _resumeWriterThreshold;

		private readonly PipeScheduler _readerScheduler;

		private readonly PipeScheduler _writerScheduler;

		private BufferSegmentStack _bufferSegmentPool;

		private readonly DefaultPipeReader _reader;

		private readonly DefaultPipeWriter _writer;

		private readonly bool _useSynchronizationContext;

		private long _unconsumedBytes;

		private long _unflushedBytes;

		private PipeAwaitable _readerAwaitable;

		private PipeAwaitable _writerAwaitable;

		private PipeCompletion _writerCompletion;

		private PipeCompletion _readerCompletion;

		private long _lastExaminedIndex = -1L;

		private BufferSegment _readHead;

		private int _readHeadIndex;

		private readonly int _maxPooledBufferSize;

		private bool _disposed;

		private BufferSegment _readTail;

		private int _readTailIndex;

		private BufferSegment _writingHead;

		private Memory<byte> _writingHeadMemory;

		private int _writingHeadBytesBuffered;

		private PipeOperationState _operationState;

		internal long Length => _unconsumedBytes;

		public PipeReader Reader => _reader;

		public PipeWriter Writer => _writer;

		public Pipe()
			: this(PipeOptions.Default)
		{
		}

		public Pipe(PipeOptions options)
		{
			if (options == null)
			{
				ThrowHelper.ThrowArgumentNullException(ExceptionArgument.options);
			}
			_bufferSegmentPool = new BufferSegmentStack(16);
			_operationState = default(PipeOperationState);
			_readerCompletion = default(PipeCompletion);
			_writerCompletion = default(PipeCompletion);
			_pool = ((options.Pool == MemoryPool<byte>.Shared) ? null : options.Pool);
			_maxPooledBufferSize = _pool?.MaxBufferSize ?? 0;
			_minimumSegmentSize = options.MinimumSegmentSize;
			_pauseWriterThreshold = options.PauseWriterThreshold;
			_resumeWriterThreshold = options.ResumeWriterThreshold;
			_readerScheduler = options.ReaderScheduler;
			_writerScheduler = options.WriterScheduler;
			_useSynchronizationContext = options.UseSynchronizationContext;
			_readerAwaitable = new PipeAwaitable(completed: false, _useSynchronizationContext);
			_writerAwaitable = new PipeAwaitable(completed: true, _useSynchronizationContext);
			_reader = new DefaultPipeReader(this);
			_writer = new DefaultPipeWriter(this);
		}

		private void ResetState()
		{
			_readerCompletion.Reset();
			_writerCompletion.Reset();
			_readerAwaitable = new PipeAwaitable(completed: false, _useSynchronizationContext);
			_writerAwaitable = new PipeAwaitable(completed: true, _useSynchronizationContext);
			_readTailIndex = 0;
			_readHeadIndex = 0;
			_lastExaminedIndex = -1L;
			_unflushedBytes = 0L;
			_unconsumedBytes = 0L;
		}

		internal Memory<byte> GetMemory(int sizeHint)
		{
			if (_writerCompletion.IsCompleted)
			{
				ThrowHelper.ThrowInvalidOperationException_NoWritingAllowed();
			}
			if (sizeHint < 0)
			{
				ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.minimumSize);
			}
			AllocateWriteHeadIfNeeded(sizeHint);
			return _writingHeadMemory;
		}

		internal Span<byte> GetSpan(int sizeHint)
		{
			if (_writerCompletion.IsCompleted)
			{
				ThrowHelper.ThrowInvalidOperationException_NoWritingAllowed();
			}
			if (sizeHint < 0)
			{
				ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.minimumSize);
			}
			AllocateWriteHeadIfNeeded(sizeHint);
			return _writingHeadMemory.Span;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void AllocateWriteHeadIfNeeded(int sizeHint)
		{
			if (!_operationState.IsWritingActive || _writingHeadMemory.Length == 0 || _writingHeadMemory.Length < sizeHint)
			{
				AllocateWriteHeadSynchronized(sizeHint);
			}
		}

		private void AllocateWriteHeadSynchronized(int sizeHint)
		{
			lock (_sync)
			{
				_operationState.BeginWrite();
				if (_writingHead == null)
				{
					BufferSegment readTail = AllocateSegment(sizeHint);
					_writingHead = (_readHead = (_readTail = readTail));
					_lastExaminedIndex = 0L;
					return;
				}
				int length = _writingHeadMemory.Length;
				if (length == 0 || length < sizeHint)
				{
					if (_writingHeadBytesBuffered > 0)
					{
						_writingHead.End += _writingHeadBytesBuffered;
						_writingHeadBytesBuffered = 0;
					}
					BufferSegment bufferSegment = AllocateSegment(sizeHint);
					_writingHead.SetNext(bufferSegment);
					_writingHead = bufferSegment;
				}
			}
		}

		private BufferSegment AllocateSegment(int sizeHint)
		{
			BufferSegment bufferSegment = CreateSegmentUnsynchronized();
			int maxPooledBufferSize = _maxPooledBufferSize;
			if (_pool != null && sizeHint <= maxPooledBufferSize)
			{
				bufferSegment.SetOwnedMemory(_pool.Rent(GetSegmentSize(sizeHint, maxPooledBufferSize)));
			}
			else
			{
				int segmentSize = GetSegmentSize(sizeHint);
				bufferSegment.SetOwnedMemory(ArrayPool<byte>.Shared.Rent(segmentSize));
			}
			_writingHeadMemory = bufferSegment.AvailableMemory;
			return bufferSegment;
		}

		private int GetSegmentSize(int sizeHint, int maxBufferSize = int.MaxValue)
		{
			sizeHint = Math.Max(_minimumSegmentSize, sizeHint);
			return Math.Min(maxBufferSize, sizeHint);
		}

		private BufferSegment CreateSegmentUnsynchronized()
		{
			if (_bufferSegmentPool.TryPop(out BufferSegment result))
			{
				return result;
			}
			return new BufferSegment();
		}

		private void ReturnSegmentUnsynchronized(BufferSegment segment)
		{
			if (_bufferSegmentPool.Count < 256)
			{
				_bufferSegmentPool.Push(segment);
			}
		}

		internal bool CommitUnsynchronized()
		{
			_operationState.EndWrite();
			if (_unflushedBytes == 0L)
			{
				return true;
			}
			_writingHead.End += _writingHeadBytesBuffered;
			_readTail = _writingHead;
			_readTailIndex = _writingHead.End;
			long unconsumedBytes = _unconsumedBytes;
			_unconsumedBytes += _unflushedBytes;
			if (_pauseWriterThreshold > 0 && unconsumedBytes < _pauseWriterThreshold && _unconsumedBytes >= _pauseWriterThreshold && !_readerCompletion.IsCompleted)
			{
				_writerAwaitable.SetUncompleted();
			}
			_unflushedBytes = 0L;
			_writingHeadBytesBuffered = 0;
			return false;
		}

		internal void Advance(int bytes)
		{
			lock (_sync)
			{
				if ((uint)bytes > (uint)_writingHeadMemory.Length)
				{
					ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes);
				}
				if (!_readerCompletion.IsCompleted)
				{
					AdvanceCore(bytes);
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void AdvanceCore(int bytesWritten)
		{
			_unflushedBytes += bytesWritten;
			_writingHeadBytesBuffered += bytesWritten;
			_writingHeadMemory = _writingHeadMemory.Slice(bytesWritten);
		}

		internal ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken)
		{
			CompletionData completionData;
			ValueTask<FlushResult> result;
			lock (_sync)
			{
				PrepareFlush(out completionData, out result, cancellationToken);
			}
			TrySchedule(_readerScheduler, in completionData);
			return result;
		}

		private void PrepareFlush(out CompletionData completionData, out ValueTask<FlushResult> result, CancellationToken cancellationToken)
		{
			bool flag = CommitUnsynchronized();
			_writerAwaitable.BeginOperation(cancellationToken, s_signalWriterAwaitable, this);
			if (_writerAwaitable.IsCompleted)
			{
				FlushResult result2 = default(FlushResult);
				GetFlushResult(ref result2);
				result = new ValueTask<FlushResult>(result2);
			}
			else
			{
				result = new ValueTask<FlushResult>(_writer, 0);
			}
			if (!flag)
			{
				_readerAwaitable.Complete(out completionData);
			}
			else
			{
				completionData = default(CompletionData);
			}
		}

		internal void CompleteWriter(Exception? exception)
		{
			PipeCompletionCallbacks pipeCompletionCallbacks;
			CompletionData completionData;
			bool isCompleted;
			lock (_sync)
			{
				CommitUnsynchronized();
				pipeCompletionCallbacks = _writerCompletion.TryComplete(exception);
				_readerAwaitable.Complete(out completionData);
				isCompleted = _readerCompletion.IsCompleted;
			}
			if (isCompleted)
			{
				CompletePipe();
			}
			if (pipeCompletionCallbacks != null)
			{
				ScheduleCallbacks(_readerScheduler, pipeCompletionCallbacks);
			}
			TrySchedule(_readerScheduler, in completionData);
		}

		internal void AdvanceReader(in SequencePosition consumed)
		{
			AdvanceReader(in consumed, in consumed);
		}

		internal void AdvanceReader(in SequencePosition consumed, in SequencePosition examined)
		{
			if (_readerCompletion.IsCompleted)
			{
				ThrowHelper.ThrowInvalidOperationException_NoReadingAllowed();
			}
			AdvanceReader((BufferSegment)((SequencePosition)(ref consumed)).GetObject(), ((SequencePosition)(ref consumed)).GetInteger(), (BufferSegment)((SequencePosition)(ref examined)).GetObject(), ((SequencePosition)(ref examined)).GetInteger());
		}

		private void AdvanceReader(BufferSegment consumedSegment, int consumedIndex, BufferSegment examinedSegment, int examinedIndex)
		{
			if (consumedSegment != null && examinedSegment != null && BufferSegment.GetLength(consumedSegment, consumedIndex, examinedSegment, examinedIndex) < 0)
			{
				ThrowHelper.ThrowInvalidOperationException_InvalidExaminedOrConsumedPosition();
			}
			BufferSegment bufferSegment = null;
			BufferSegment returnEnd = null;
			CompletionData completionData = default(CompletionData);
			lock (_sync)
			{
				bool flag = false;
				if (examinedSegment == _readTail)
				{
					flag = examinedIndex == _readTailIndex;
				}
				if (examinedSegment != null && _lastExaminedIndex >= 0)
				{
					long length = BufferSegment.GetLength(_lastExaminedIndex, examinedSegment, examinedIndex);
					long unconsumedBytes = _unconsumedBytes;
					if (length < 0)
					{
						ThrowHelper.ThrowInvalidOperationException_InvalidExaminedPosition();
					}
					_unconsumedBytes -= length;
					_lastExaminedIndex = ((ReadOnlySequenceSegment<byte>)examinedSegment).RunningIndex + examinedIndex;
					if (unconsumedBytes >= _resumeWriterThreshold && _unconsumedBytes < _resumeWriterThreshold)
					{
						_writerAwaitable.Complete(out completionData);
					}
				}
				if (consumedSegment != null)
				{
					if (_readHead == null)
					{
						ThrowHelper.ThrowInvalidOperationException_AdvanceToInvalidCursor();
						return;
					}
					bufferSegment = _readHead;
					returnEnd = consumedSegment;
					if (consumedIndex == returnEnd.Length)
					{
						if (_writingHead != returnEnd)
						{
							MoveReturnEndToNextBlock();
						}
						else if (_writingHeadBytesBuffered == 0 && !_operationState.IsWritingActive)
						{
							_writingHead = null;
							_writingHeadMemory = default(Memory<byte>);
							MoveReturnEndToNextBlock();
						}
						else
						{
							_readHead = consumedSegment;
							_readHeadIndex = consumedIndex;
						}
					}
					else
					{
						_readHead = consumedSegment;
						_readHeadIndex = consumedIndex;
					}
				}
				if (flag && !_writerCompletion.IsCompleted)
				{
					_readerAwaitable.SetUncompleted();
				}
				while (bufferSegment != null && bufferSegment != returnEnd)
				{
					BufferSegment nextSegment = bufferSegment.NextSegment;
					bufferSegment.ResetMemory();
					ReturnSegmentUnsynchronized(bufferSegment);
					bufferSegment = nextSegment;
				}
				_operationState.EndRead();
			}
			TrySchedule(_writerScheduler, in completionData);
			void MoveReturnEndToNextBlock()
			{
				BufferSegment nextSegment2 = returnEnd.NextSegment;
				if (_readTail == returnEnd)
				{
					_readTail = nextSegment2;
					_readTailIndex = 0;
				}
				_readHead = nextSegment2;
				_readHeadIndex = 0;
				returnEnd = nextSegment2;
			}
		}

		internal void CompleteReader(Exception? exception)
		{
			PipeCompletionCallbacks pipeCompletionCallbacks;
			CompletionData completionData;
			bool isCompleted;
			lock (_sync)
			{
				if (_operationState.IsReadingActive)
				{
					_operationState.EndRead();
				}
				pipeCompletionCallbacks = _readerCompletion.TryComplete(exception);
				_writerAwaitable.Complete(out completionData);
				isCompleted = _writerCompletion.IsCompleted;
			}
			if (isCompleted)
			{
				CompletePipe();
			}
			if (pipeCompletionCallbacks != null)
			{
				ScheduleCallbacks(_writerScheduler, pipeCompletionCallbacks);
			}
			TrySchedule(_writerScheduler, in completionData);
		}

		internal void OnWriterCompleted(Action<Exception?, object?> callback, object? state)
		{
			if (callback == null)
			{
				ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback);
			}
			PipeCompletionCallbacks pipeCompletionCallbacks;
			lock (_sync)
			{
				pipeCompletionCallbacks = _writerCompletion.AddCallback(callback, state);
			}
			if (pipeCompletionCallbacks != null)
			{
				ScheduleCallbacks(_readerScheduler, pipeCompletionCallbacks);
			}
		}

		internal void CancelPendingRead()
		{
			CompletionData completionData;
			lock (_sync)
			{
				_readerAwaitable.Cancel(out completionData);
			}
			TrySchedule(_readerScheduler, in completionData);
		}

		internal void CancelPendingFlush()
		{
			CompletionData completionData;
			lock (_sync)
			{
				_writerAwaitable.Cancel(out completionData);
			}
			TrySchedule(_writerScheduler, in completionData);
		}

		internal void OnReaderCompleted(Action<Exception?, object?> callback, object? state)
		{
			if (callback == null)
			{
				ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback);
			}
			PipeCompletionCallbacks pipeCompletionCallbacks;
			lock (_sync)
			{
				pipeCompletionCallbacks = _readerCompletion.AddCallback(callback, state);
			}
			if (pipeCompletionCallbacks != null)
			{
				ScheduleCallbacks(_writerScheduler, pipeCompletionCallbacks);
			}
		}

		internal ValueTask<ReadResult> ReadAsync(CancellationToken token)
		{
			if (_readerCompletion.IsCompleted)
			{
				ThrowHelper.ThrowInvalidOperationException_NoReadingAllowed();
			}
			lock (_sync)
			{
				_readerAwaitable.BeginOperation(token, s_signalReaderAwaitable, this);
				if (_readerAwaitable.IsCompleted)
				{
					GetReadResult(out var result);
					return new ValueTask<ReadResult>(result);
				}
				return new ValueTask<ReadResult>(_reader, 0);
			}
		}

		internal bool TryRead(out ReadResult result)
		{
			lock (_sync)
			{
				if (_readerCompletion.IsCompleted)
				{
					ThrowHelper.ThrowInvalidOperationException_NoReadingAllowed();
				}
				if (_unconsumedBytes > 0 || _readerAwaitable.IsCompleted)
				{
					GetReadResult(out result);
					return true;
				}
				if (_readerAwaitable.IsRunning)
				{
					ThrowHelper.ThrowInvalidOperationException_AlreadyReading();
				}
				_operationState.BeginReadTentative();
				result = default(ReadResult);
				return false;
			}
		}

		private static void ScheduleCallbacks(PipeScheduler scheduler, PipeCompletionCallbacks completionCallbacks)
		{
			scheduler.UnsafeSchedule(s_invokeCompletionCallbacks, completionCallbacks);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static void TrySchedule(PipeScheduler scheduler, in CompletionData completionData)
		{
			Action<object> completion = completionData.Completion;
			if (completion != null)
			{
				if (completionData.SynchronizationContext == null && completionData.ExecutionContext == null)
				{
					scheduler.UnsafeSchedule(completion, completionData.CompletionState);
				}
				else
				{
					ScheduleWithContext(scheduler, in completionData);
				}
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void ScheduleWithContext(PipeScheduler scheduler, in CompletionData completionData)
		{
			if (completionData.SynchronizationContext == null)
			{
				scheduler.UnsafeSchedule(s_scheduleWithExecutionContextCallback, completionData);
			}
			else if (completionData.ExecutionContext == null)
			{
				completionData.SynchronizationContext.Post(s_syncContextExecuteWithoutExecutionContextCallback, completionData);
			}
			else
			{
				completionData.SynchronizationContext.Post(s_syncContextExecutionContextCallback, completionData);
			}
		}

		private static void ExecuteWithoutExecutionContext(object state)
		{
			CompletionData completionData = (CompletionData)state;
			completionData.Completion(completionData.CompletionState);
		}

		private static void ExecuteWithExecutionContext(object state)
		{
			ExecutionContext.Run(((CompletionData)state).ExecutionContext, s_executionContextRawCallback, state);
		}

		private void CompletePipe()
		{
			lock (_sync)
			{
				if (!_disposed)
				{
					_disposed = true;
					BufferSegment bufferSegment = _readHead ?? _readTail;
					while (bufferSegment != null)
					{
						BufferSegment bufferSegment2 = bufferSegment;
						bufferSegment = bufferSegment.NextSegment;
						bufferSegment2.ResetMemory();
					}
					_writingHead = null;
					_readHead = null;
					_readTail = null;
					_lastExaminedIndex = -1L;
				}
			}
		}

		internal ValueTaskSourceStatus GetReadAsyncStatus()
		{
			if (_readerAwaitable.IsCompleted)
			{
				if (_writerCompletion.IsFaulted)
				{
					return ValueTaskSourceStatus.Faulted;
				}
				return ValueTaskSourceStatus.Succeeded;
			}
			return ValueTaskSourceStatus.Pending;
		}

		internal void OnReadAsyncCompleted(Action<object?> continuation, object? state, ValueTaskSourceOnCompletedFlags flags)
		{
			CompletionData completionData;
			bool doubleCompletion;
			lock (_sync)
			{
				_readerAwaitable.OnCompleted(continuation, state, flags, out completionData, out doubleCompletion);
			}
			if (doubleCompletion)
			{
				Writer.Complete(ThrowHelper.CreateInvalidOperationException_NoConcurrentOperation());
			}
			TrySchedule(_readerScheduler, in completionData);
		}

		internal ReadResult GetReadAsyncResult()
		{
			CancellationTokenRegistration cancellationTokenRegistration = default(CancellationTokenRegistration);
			CancellationToken cancellationToken = default(CancellationToken);
			ReadResult result;
			try
			{
				lock (_sync)
				{
					if (!_readerAwaitable.IsCompleted)
					{
						ThrowHelper.ThrowInvalidOperationException_GetResultNotCompleted();
					}
					cancellationTokenRegistration = _readerAwaitable.ReleaseCancellationTokenRegistration(out cancellationToken);
					GetReadResult(out result);
				}
			}
			finally
			{
				cancellationTokenRegistration.Dispose();
			}
			if (result.IsCanceled)
			{
				cancellationToken.ThrowIfCancellationRequested();
			}
			return result;
		}

		private void GetReadResult(out ReadResult result)
		{
			//IL_004f: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			bool isCompleted = _writerCompletion.IsCompletedOrThrow();
			bool flag = _readerAwaitable.ObserveCancellation();
			BufferSegment readHead = _readHead;
			if (readHead != null)
			{
				ReadOnlySequence<byte> buffer = default(ReadOnlySequence<byte>);
				buffer..ctor((ReadOnlySequenceSegment<byte>)readHead, _readHeadIndex, (ReadOnlySequenceSegment<byte>)_readTail, _readTailIndex);
				result = new ReadResult(buffer, flag, isCompleted);
			}
			else
			{
				result = new ReadResult(default(ReadOnlySequence<byte>), flag, isCompleted);
			}
			if (flag)
			{
				_operationState.BeginReadTentative();
			}
			else
			{
				_operationState.BeginRead();
			}
		}

		internal ValueTaskSourceStatus GetFlushAsyncStatus()
		{
			if (_writerAwaitable.IsCompleted)
			{
				if (_readerCompletion.IsFaulted)
				{
					return ValueTaskSourceStatus.Faulted;
				}
				return ValueTaskSourceStatus.Succeeded;
			}
			return ValueTaskSourceStatus.Pending;
		}

		internal FlushResult GetFlushAsyncResult()
		{
			FlushResult result = default(FlushResult);
			CancellationToken cancellationToken = default(CancellationToken);
			CancellationTokenRegistration cancellationTokenRegistration = default(CancellationTokenRegistration);
			try
			{
				lock (_sync)
				{
					if (!_writerAwaitable.IsCompleted)
					{
						ThrowHelper.ThrowInvalidOperationException_GetResultNotCompleted();
					}
					GetFlushResult(ref result);
					cancellationTokenRegistration = _writerAwaitable.ReleaseCancellationTokenRegistration(out cancellationToken);
					return result;
				}
			}
			finally
			{
				cancellationTokenRegistration.Dispose();
				cancellationToken.ThrowIfCancellationRequested();
			}
		}

		private void GetFlushResult(ref FlushResult result)
		{
			if (_writerAwaitable.ObserveCancellation())
			{
				result._resultFlags |= ResultFlags.Canceled;
			}
			if (_readerCompletion.IsCompletedOrThrow())
			{
				result._resultFlags |= ResultFlags.Completed;
			}
		}

		internal ValueTask<FlushResult> WriteAsync(ReadOnlyMemory<byte> source, CancellationToken cancellationToken)
		{
			if (_writerCompletion.IsCompleted)
			{
				ThrowHelper.ThrowInvalidOperationException_NoWritingAllowed();
			}
			if (_readerCompletion.IsCompletedOrThrow())
			{
				return new ValueTask<FlushResult>(new FlushResult(isCanceled: false, isCompleted: true));
			}
			CompletionData completionData;
			ValueTask<FlushResult> result;
			lock (_sync)
			{
				AllocateWriteHeadIfNeeded(0);
				if (source.Length <= _writingHeadMemory.Length)
				{
					source.CopyTo(_writingHeadMemory);
					AdvanceCore(source.Length);
				}
				else
				{
					WriteMultiSegment(source.Span);
				}
				PrepareFlush(out completionData, out result, cancellationToken);
			}
			TrySchedule(_readerScheduler, in completionData);
			return result;
		}

		private void WriteMultiSegment(ReadOnlySpan<byte> source)
		{
			Span<byte> span = _writingHeadMemory.Span;
			while (true)
			{
				int num = Math.Min(span.Length, source.Length);
				source.Slice(0, num).CopyTo(span);
				source = source.Slice(num);
				AdvanceCore(num);
				if (source.Length != 0)
				{
					_writingHead.End += _writingHeadBytesBuffered;
					_writingHeadBytesBuffered = 0;
					BufferSegment bufferSegment = AllocateSegment(0);
					_writingHead.SetNext(bufferSegment);
					_writingHead = bufferSegment;
					span = _writingHeadMemory.Span;
					continue;
				}
				break;
			}
		}

		internal void OnFlushAsyncCompleted(Action<object?> continuation, object? state, ValueTaskSourceOnCompletedFlags flags)
		{
			CompletionData completionData;
			bool doubleCompletion;
			lock (_sync)
			{
				_writerAwaitable.OnCompleted(continuation, state, flags, out completionData, out doubleCompletion);
			}
			if (doubleCompletion)
			{
				Reader.Complete(ThrowHelper.CreateInvalidOperationException_NoConcurrentOperation());
			}
			TrySchedule(_writerScheduler, in completionData);
		}

		private void ReaderCancellationRequested()
		{
			CompletionData completionData;
			lock (_sync)
			{
				_readerAwaitable.CancellationTokenFired(out completionData);
			}
			TrySchedule(_readerScheduler, in completionData);
		}

		private void WriterCancellationRequested()
		{
			CompletionData completionData;
			lock (_sync)
			{
				_writerAwaitable.CancellationTokenFired(out completionData);
			}
			TrySchedule(_writerScheduler, in completionData);
		}

		public void Reset()
		{
			lock (_sync)
			{
				if (!_disposed)
				{
					ThrowHelper.ThrowInvalidOperationException_ResetIncompleteReaderWriter();
				}
				_disposed = false;
				ResetState();
			}
		}
	}
	[DebuggerDisplay("CanceledState: {_awaitableState}, IsCompleted: {IsCompleted}")]
	internal struct PipeAwaitable
	{
		[Flags]
		private enum AwaitableState
		{
			None = 0,
			Completed = 1,
			Running = 2,
			Canceled = 4,
			UseSynchronizationContext = 8
		}

		private AwaitableState _awaitableState;

		private Action<object> _completion;

		private object _completionState;

		private CancellationTokenRegistration _cancellationTokenRegistration;

		private SynchronizationContext _synchronizationContext;

		private ExecutionContext _executionContext;

		private CancellationToken _cancellationToken;

		private CancellationToken CancellationToken => _cancellationToken;

		public bool IsCompleted => (_awaitableState & (AwaitableState.Completed | AwaitableState.Canceled)) != 0;

		public bool IsRunning => (_awaitableState & AwaitableState.Running) != 0;

		public PipeAwaitable(bool completed, bool useSynchronizationContext)
		{
			_awaitableState = (completed ? AwaitableState.Completed : AwaitableState.None) | (useSynchronizationContext ? AwaitableState.UseSynchronizationContext : AwaitableState.None);
			_completion = null;
			_completionState = null;
			_cancellationTokenRegistration = default(CancellationTokenRegistration);
			_synchronizationContext = null;
			_executionContext = null;
			_cancellationToken = CancellationToken.None;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void BeginOperation(CancellationToken cancellationToken, Action<object?> callback, object? state)
		{
			cancellationToken.ThrowIfCancellationRequested();
			_awaitableState |= AwaitableState.Running;
			if (cancellationToken.CanBeCanceled && !IsCompleted)
			{
				_cancellationToken = cancellationToken;
				_cancellationTokenRegistration = CancellationTokenExtensions.UnsafeRegister(cancellationToken, callback, state);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Complete(out CompletionData completionData)
		{
			ExtractCompletion(out completionData);
			_awaitableState |= AwaitableState.Completed;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void ExtractCompletion(out CompletionData completionData)
		{
			Action<object> completion = _completion;
			object completionState = _completionState;
			ExecutionContext executionContext = _executionContext;
			SynchronizationContext synchronizationContext = _synchronizationContext;
			_completion = null;
			_completionState = null;
			_synchronizationContext = null;
			_executionContext = null;
			completionData = ((completion != null) ? new CompletionData(completion, completionState, executionContext, synchronizationContext) : default(CompletionData));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void SetUncompleted()
		{
			_awaitableState &= ~AwaitableState.Completed;
		}

		public void OnCompleted(Action<object?> continuation, object? state, ValueTaskSourceOnCompletedFlags flags, out CompletionData completionData, out bool doubleCompletion)
		{
			completionData = default(CompletionData);
			doubleCompletion = _completion != null;
			if (IsCompleted | doubleCompletion)
			{
				completionData = new CompletionData(continuation, state, _executionContext, _synchronizationContext);
				return;
			}
			_completion = continuation;
			_completionState = state;
			if ((_awaitableState & AwaitableState.UseSynchronizationContext) != 0 && (flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0)
			{
				SynchronizationContext current = SynchronizationContext.Current;
				if (current != null && current.GetType() != typeof(SynchronizationContext))
				{
					_synchronizationContext = current;
				}
			}
			if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0)
			{
				_executionContext = ExecutionContext.Capture();
			}
		}

		public void Cancel(out CompletionData completionData)
		{
			ExtractCompletion(out completionData);
			_awaitableState |= AwaitableState.Canceled;
		}

		public void CancellationTokenFired(out CompletionData completionData)
		{
			if (CancellationToken.IsCancellationRequested)
			{
				Cancel(out completionData);
			}
			else
			{
				completionData = default(CompletionData);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool ObserveCancellation()
		{
			bool result = (_awaitableState & AwaitableState.Canceled) == AwaitableState.Canceled;
			_awaitableState &= ~(AwaitableState.Running | AwaitableState.Canceled);
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public CancellationTokenRegistration ReleaseCancellationTokenRegistration(out CancellationToken cancellationToken)
		{
			cancellationToken = CancellationToken;
			CancellationTokenRegistration cancellationTokenRegistration = _cancellationTokenRegistration;
			_cancellationToken = default(CancellationToken);
			_cancellationTokenRegistration = default(CancellationTokenRegistration);
			return cancellationTokenRegistration;
		}
	}
	[DebuggerDisplay("IsCompleted: {IsCompleted}")]
	internal struct PipeCompletion
	{
		private static readonly ArrayPool<PipeCompletionCallback> s_completionCallbackPool = ArrayPool<PipeCompletionCallback>.Shared;

		private const int InitialCallbacksSize = 1;

		private bool _isCompleted;

		private ExceptionDispatchInfo _exceptionInfo;

		private PipeCompletionCallback _firstCallback;

		private PipeCompletionCallback[] _callbacks;

		private int _callbackCount;

		public bool IsCompleted => _isCompleted;

		public bool IsFaulted => _exceptionInfo != null;

		public PipeCompletionCallbacks? TryComplete(Exception? exception = null)
		{
			if (!_isCompleted)
			{
				_isCompleted = true;
				if (exception != null)
				{
					_exceptionInfo = ExceptionDispatchInfo.Capture(exception);
				}
			}
			return GetCallbacks();
		}

		public PipeCompletionCallbacks? AddCallback(Action<Exception?, object?> callback, object? state)
		{
			if (_callbackCount == 0)
			{
				_firstCallback = new PipeCompletionCallback(callback, state);
				_callbackCount++;
			}
			else
			{
				EnsureSpace();
				int num = _callbackCount - 1;
				_callbackCount++;
				_callbacks[num] = new PipeCompletionCallback(callback, state);
			}
			if (IsCompleted)
			{
				return GetCallbacks();
			}
			return null;
		}

		private void EnsureSpace()
		{
			if (_callbacks == null)
			{
				_callbacks = s_completionCallbackPool.Rent(1);
			}
			int num = _callbackCount - 1;
			if (num == _callbacks.Length)
			{
				PipeCompletionCallback[] array = s_completionCallbackPool.Rent(_callbacks.Length * 2);
				Array.Copy(_callbacks, array, _callbacks.Length);
				s_completionCallbackPool.Return(_callbacks, clearArray: true);
				_callbacks = array;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool IsCompletedOrThrow()
		{
			if (!_isCompleted)
			{
				return false;
			}
			if (_exceptionInfo != null)
			{
				ThrowLatchedException();
			}
			return true;
		}

		private PipeCompletionCallbacks GetCallbacks()
		{
			if (_callbackCount == 0)
			{
				return null;
			}
			PipeCompletionCallbacks result = new PipeCompletionCallbacks(s_completionCallbackPool, _callbackCount, _exceptionInfo?.SourceException, _firstCallback, _callbacks);
			_firstCallback = default(PipeCompletionCallback);
			_callbacks = null;
			_callbackCount = 0;
			return result;
		}

		public void Reset()
		{
			_isCompleted = false;
			_exceptionInfo = null;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void ThrowLatchedException()
		{
			_exceptionInfo.Throw();
		}

		public override string ToString()
		{
			return string.Format("{0}: {1}", "IsCompleted", IsCompleted);
		}
	}
	internal struct PipeCompletionCallback
	{
		public Action<Exception?, object?> Callback;

		public object? State;

		public PipeCompletionCallback(Action<Exception?, object?> callback, object? state)
		{
			Callback = callback;
			State = state;
		}
	}
	internal sealed class PipeCompletionCallbacks
	{
		private readonly ArrayPool<PipeCompletionCallback> _pool;

		private readonly int _count;

		private readonly Exception _exception;

		private readonly PipeCompletionCallback _firstCallback;

		private readonly PipeCompletionCallback[] _callbacks;

		public PipeCompletionCallbacks(ArrayPool<PipeCompletionCallback> pool, int count, Exception? exception, PipeCompletionCallback firstCallback, PipeCompletionCallback[]? callbacks)
		{
			_pool = pool;
			_count = count;
			_exception = exception;
			_firstCallback = firstCallback;
			_callbacks = callbacks;
		}

		public void Execute()
		{
			if (_count == 0)
			{
				return;
			}
			List<Exception> exceptions = null;
			Execute(_firstCallback, ref exceptions);
			if (_callbacks != null)
			{
				try
				{
					for (int i = 0; i < _count - 1; i++)
					{
						PipeCompletionCallback callback = _callbacks[i];
						Execute(callback, ref exceptions);
					}
				}
				finally
				{
					_pool.Return(_callbacks, clearArray: true);
				}
			}
			if (exceptions == null)
			{
				return;
			}
			throw new AggregateException(exceptions);
		}

		private void Execute(PipeCompletionCallback callback, ref List<Exception> exceptions)
		{
			try
			{
				callback.Callback(_exception, callback.State);
			}
			catch (Exception item)
			{
				if (exceptions == null)
				{
					exceptions = new List<Exception>();
				}
				exceptions.Add(item);
			}
		}
	}
	public class PipeOptions
	{
		private const int DefaultMinimumSegmentSize = 4096;

		private const int DefaultResumeWriterThreshold = 32768;

		private const int DefaultPauseWriterThreshold = 65536;

		public static PipeOptions Default { get; } = new PipeOptions(null, null, null, -1L, -1L);


		public bool UseSynchronizationContext { get; }

		public long PauseWriterThreshold { get; }

		public long ResumeWriterThreshold { get; }

		public int MinimumSegmentSize { get; }

		public PipeScheduler WriterScheduler { get; }

		public PipeScheduler ReaderScheduler { get; }

		public MemoryPool<byte> Pool { get; }

		public PipeOptions(MemoryPool<byte>? pool = null, PipeScheduler? readerScheduler = null, PipeScheduler? writerScheduler = null, long pauseWriterThreshold = -1L, long resumeWriterThreshold = -1L, int minimumSegmentSize = -1, bool useSynchronizationContext = true)
		{
			if (pauseWriterThreshold == -1)
			{
				pauseWriterThreshold = 65536L;
			}
			else if (pauseWriterThreshold < 0)
			{
				ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.pauseWriterThreshold);
			}
			if (resumeWriterThreshold == -1)
			{
				resumeWriterThreshold = 32768L;
			}
			else if (resumeWriterThreshold < 0 || resumeWriterThreshold > pauseWriterThreshold)
			{
				ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.resumeWriterThreshold);
			}
			Pool = pool ?? MemoryPool<byte>.Shared;
			ReaderScheduler = readerScheduler ?? PipeScheduler.ThreadPool;
			WriterScheduler = writerScheduler ?? PipeScheduler.ThreadPool;
			PauseWriterThreshold = pauseWriterThreshold;
			ResumeWriterThreshold = resumeWriterThreshold;
			MinimumSegmentSize = ((minimumSegmentSize == -1) ? 4096 : minimumSegmentSize);
			UseSynchronizationContext = useSynchronizationContext;
		}
	}
	public abstract class PipeReader
	{
		private PipeReaderStream _stream;

		public abstract bool TryRead(out ReadResult result);

		public abstract ValueTask<ReadResult> ReadAsync(CancellationToken cancellationToken = default(CancellationToken));

		public abstract void AdvanceTo(SequencePosition consumed);

		public abstract void AdvanceTo(SequencePosition consumed, SequencePosition examined);

		public virtual Stream AsStream(bool leaveOpen = false)
		{
			if (_stream == null)
			{
				_stream = new PipeReaderStream(this, leaveOpen);
			}
			else if (leaveOpen)
			{
				_stream.LeaveOpen = leaveOpen;
			}
			return _stream;
		}

		public abstract void CancelPendingRead();

		public abstract void Complete(Exception? exception = null);

		public virtual ValueTask CompleteAsync(Exception? exception = null)
		{
			try
			{
				Complete(exception);
				return default(ValueTask);
			}
			catch (Exception exception2)
			{
				return new ValueTask(Task.FromException(exception2));
			}
		}

		[Obsolete("OnWriterCompleted may not be invoked on all implementations of PipeReader. This will be removed in a future release.")]
		public virtual void OnWriterCompleted(Action<Exception?, object?> callback, object? state)
		{
		}

		public static PipeReader Create(Stream stream, StreamPipeReaderOptions? readerOptions = null)
		{
			return new StreamPipeReader(stream, readerOptions ?? StreamPipeReaderOptions.s_default);
		}

		public virtual Task CopyToAsync(PipeWriter destination, CancellationToken cancellationToken = default(CancellationToken))
		{
			if (destination == null)
			{
				throw new ArgumentNullException("destination");
			}
			if (cancellationToken.IsCancellationRequested)
			{
				return Task.FromCanceled(cancellationToken);
			}
			return CopyToAsyncCore(destination, async delegate(PipeWriter destination, ReadOnlyMemory<byte> memory, CancellationToken cancellationToken)
			{
				if ((await destination.WriteAsync(memory, cancellationToken).ConfigureAwait(continueOnCapturedContext: false)).IsCanceled)
				{
					ThrowHelper.ThrowOperationCanceledException_FlushCanceled();
				}
			}, cancellationToken);
		}

		public virtual Task CopyToAsync(Stream destination, CancellationToken cancellationToken = default(CancellationToken))
		{
			if (destination == null)
			{
				throw new ArgumentNullException("destination");
			}
			if (cancellationToken.IsCancellationRequested)
			{
				return Task.FromCanceled(cancellationToken);
			}
			return CopyToAsyncCore(destination, (Stream destination, ReadOnlyMemory<byte> memory, CancellationToken cancellationToken) => StreamExtensions.WriteAsync(destination, memory, cancellationToken), cancellationToken);
		}

		private async Task CopyToAsyncCore<TStream>(TStream destination, Func<TStream, ReadOnlyMemory<byte>, CancellationToken, ValueTask> writeAsync, CancellationToken cancellationToken)
		{
			ReadOnlyMemory<byte> arg = default(ReadOnlyMemory<byte>);
			while (true)
			{
				ReadResult result = await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
				ReadOnlySequence<byte> buffer = result.Buffer;
				SequencePosition position = buffer.Start;
				SequencePosition consumed = position;
				try
				{
					if (result.IsCanceled)
					{
						ThrowHelper.ThrowOperationCanceledException_ReadCanceled();
					}
					while (buffer.TryGet(ref position, ref arg, true))
					{
						await writeAsync(destination, arg, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
						consumed = position;
					}
					consumed = buffer.End;
					if (result.IsCompleted)
					{
						break;
					}
				}
				finally
				{
					AdvanceTo(consumed);
				}
			}
		}
	}
	[DebuggerDisplay("State: {_state}")]
	internal struct PipeOperationState
	{
		[Flags]
		internal enum State : byte
		{
			Reading = 1,
			ReadingTentative = 2,
			Writing = 4
		}

		private State _state;

		public bool IsWritingActive => (_state & State.Writing) == State.Writing;

		public bool IsReadingActive => (_state & State.Reading) == State.Reading;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void BeginRead()
		{
			if ((_state & State.Reading) == State.Reading)
			{
				ThrowHelper.ThrowInvalidOperationException_AlreadyReading();
			}
			_state |= State.Reading;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void BeginReadTentative()
		{
			if ((_state & State.Reading) == State.Reading)
			{
				ThrowHelper.ThrowInvalidOperationException_AlreadyReading();
			}
			_state |= State.ReadingTentative;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void EndRead()
		{
			if ((_state & State.Reading) != State.Reading && (_state & State.ReadingTentative) != State.ReadingTentative)
			{
				ThrowHelper.ThrowInvalidOperationException_NoReadToComplete();
			}
			_state &= ~(State.Reading | State.ReadingTentative);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void BeginWrite()
		{
			_state |= State.Writing;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void EndWrite()
		{
			_state &= ~State.Writing;
		}
	}
	internal sealed class PipeReaderStream : Stream
	{
		private readonly PipeReader _pipeReader;

		public override bool CanRead => true;

		public override bool CanSeek => false;

		public override bool CanWrite => false;

		public override long Length
		{
			get
			{
				throw new NotSupportedException();
			}
		}

		public override long Position
		{
			get
			{
				throw new NotSupportedException();
			}
			set
			{
				throw new NotSupportedException();
			}
		}

		internal bool LeaveOpen { get; set; }

		public PipeReaderStream(PipeReader pipeReader, bool leaveOpen)
		{
			_pipeReader = pipeReader;
			LeaveOpen = leaveOpen;
		}

		protected override void Dispose(bool disposing)
		{
			if (!LeaveOpen)
			{
				_pipeReader.Complete();
			}
			base.Dispose(disposing);
		}

		public override void Flush()
		{
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			return ReadAsync(buffer, offset, count).GetAwaiter().GetResult();
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			throw new NotSupportedException();
		}

		public override void SetLength(long value)
		{
			throw new NotSupportedException();
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			throw new NotSupportedException();
		}

		public sealed override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
		{
			return System.Threading.Tasks.TaskToApm.Begin(ReadAsync(buffer, offset, count, default(CancellationToken)), callback, state);
		}

		public sealed override int EndRead(IAsyncResult asyncResult)
		{
			return System.Threading.Tasks.TaskToApm.End<int>(asyncResult);
		}

		public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
		{
			return ReadAsyncInternal(new Memory<byte>(buffer, offset, count), cancellationToken).AsTask();
		}

		private async ValueTask<int> ReadAsyncInternal(Memory<byte> buffer, CancellationToken cancellationToken)
		{
			ReadResult readResult = await _pipeReader.ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			if (readResult.IsCanceled)
			{
				ThrowHelper.ThrowOperationCanceledException_ReadCanceled();
			}
			ReadOnlySequence<byte> buffer2 = readResult.Buffer;
			long length = buffer2.Length;
			SequencePosition consumed = buffer2.Start;
			try
			{
				if (length != 0L)
				{
					int num = (int)Math.Min(length, buffer.Length);
					ReadOnlySequence<byte> val = ((num == length) ? buffer2 : buffer2.Slice(0, num));
					consumed = val.End;
					BuffersExtensions.CopyTo<byte>(ref val, buffer.Span);
					return num;
				}
				if (readResult.IsCompleted)
				{
					return 0;
				}
			}
			finally
			{
				_pipeReader.AdvanceTo(consumed);
			}
			ThrowHelper.ThrowInvalidOperationException_InvalidZeroByteRead();
			return 0;
		}

		public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
		{
			return _pipeReader.CopyToAsync(destination, cancellationToken);
		}
	}
	public abstract class PipeScheduler
	{
		private static readonly ThreadPoolScheduler s_threadPoolScheduler = new ThreadPoolScheduler();

		private static readonly InlineScheduler s_inlineScheduler = new InlineScheduler();

		public static PipeScheduler ThreadPool => s_threadPoolScheduler;

		public static PipeScheduler Inline => s_inlineScheduler;

		public abstract void Schedule(Action<object?> action, object? state);

		internal virtual void UnsafeSchedule(Action<object?> action, object? state)
		{
			Schedule(action, state);
		}
	}
	public abstract class PipeWriter : IBufferWriter<byte>
	{
		private PipeWriterStream _stream;

		public abstract void Complete(Exception? exception = null);

		public virtual ValueTask CompleteAsync(Exception? exception = null)
		{
			try
			{
				Complete(exception);
				return default(ValueTask);
			}
			catch (Exception exception2)
			{
				return new ValueTask(Task.FromException(exception2));
			}
		}

		public abstract void CancelPendingFlush();

		[Obsolete("OnReaderCompleted may not be invoked on all implementations of PipeWriter. This will be removed in a future release.")]
		public virtual void OnReaderCompleted(Action<Exception?, object?> callback, object? state)
		{
		}

		public abstract ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken = default(CancellationToken));

		public abstract void Advance(int bytes);

		public abstract Memory<byte> GetMemory(int sizeHint = 0);

		public abstract Span<byte> GetSpan(int sizeHint = 0);

		public virtual Stream AsStream(bool leaveOpen = false)
		{
			if (_stream == null)
			{
				_stream = new PipeWriterStream(this, leaveOpen);
			}
			else if (leaveOpen)
			{
				_stream.LeaveOpen = leaveOpen;
			}
			return _stream;
		}

		public static PipeWriter Create(Stream stream, StreamPipeWriterOptions? writerOptions = null)
		{
			return new StreamPipeWriter(stream, writerOptions ?? StreamPipeWriterOptions.s_default);
		}

		public virtual ValueTask<FlushResult> WriteAsync(ReadOnlyMemory<byte> source, CancellationToken cancellationToken = default(CancellationToken))
		{
			BuffersExtensions.Write<byte>((IBufferWriter<byte>)this, source.Span);
			return FlushAsync(cancellationToken);
		}

		protected internal virtual async Task CopyFromAsync(Stream source, CancellationToken cancellationToken = default(CancellationToken))
		{
			FlushResult flushResult;
			do
			{
				Memory<byte> memory = GetMemory();
				int num = await StreamExtensions.ReadAsync(source, memory, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
				if (num != 0)
				{
					Advance(num);
					flushResult = await FlushAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
					if (flushResult.IsCanceled)
					{
						ThrowHelper.ThrowOperationCanceledException_FlushCanceled();
					}
					continue;
				}
				break;
			}
			while (!flushResult.IsCompleted);
		}
	}
	internal sealed class PipeWriterStream : Stream
	{
		private readonly PipeWriter _pipeWriter;

		internal bool LeaveOpen { get; set; }

		public override bool CanRead => false;

		public override bool CanSeek => false;

		public override bool CanWrite => true;

		public override long Length
		{
			get
			{
				throw new NotSupportedException();
			}
		}

		public override long Position
		{
			get
			{
				throw new NotSupportedException();
			}
			set
			{
				throw new NotSupportedException();
			}
		}

		public PipeWriterStream(PipeWriter pipeWriter, bool leaveOpen)
		{
			_pipeWriter = pipeWriter;
			LeaveOpen = leaveOpen;
		}

		protected override void Dispose(bool disposing)
		{
			if (!LeaveOpen)
			{
				_pipeWriter.Complete();
			}
			base.Dispose(disposing);
		}

		public override void Flush()
		{
			FlushAsync().GetAwaiter().GetResult();
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			throw new NotSupportedException();
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			throw new NotSupportedException();
		}

		public override void SetLength(long value)
		{
			throw new NotSupportedException();
		}

		public sealed override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
		{
			return System.Threading.Tasks.TaskToApm.Begin(WriteAsync(buffer, offset, count, default(CancellationToken)), callback, state);
		}

		public sealed override void EndWrite(IAsyncResult asyncResult)
		{
			System.Threading.Tasks.TaskToApm.End(asyncResult);
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			WriteAsync(buffer, offset, count).GetAwaiter().GetResult();
		}

		public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
		{
			ValueTask<FlushResult> valueTask = _pipeWriter.WriteAsync(new ReadOnlyMemory<byte>(buffer, offset, count), cancellationToken);
			return GetFlushResultAsTask(valueTask);
		}

		public override Task FlushAsync(CancellationToken cancellationToken)
		{
			ValueTask<FlushResult> valueTask = _pipeWriter.FlushAsync(cancellationToken);
			return GetFlushResultAsTask(valueTask);
		}

		private static Task GetFlushResultAsTask(ValueTask<FlushResult> valueTask)
		{
			if (valueTask.IsCompletedSuccessfully)
			{
				if (valueTask.Result.IsCanceled)
				{
					ThrowHelper.ThrowOperationCanceledException_FlushCanceled();
				}
				return Task.CompletedTask;
			}
			return AwaitTask(valueTask);
			static async Task AwaitTask(ValueTask<FlushResult> valueTask)
			{
				if ((await valueTask.ConfigureAwait(continueOnCapturedContext: false)).IsCanceled)
				{
					ThrowHelper.ThrowOperationCanceledException_FlushCanceled();
				}
			}
		}
	}
	public readonly struct ReadResult
	{
		internal readonly ReadOnlySequence<byte> _resultBuffer;

		internal readonly ResultFlags _resultFlags;

		public ReadOnlySequence<byte> Buffer => _resultBuffer;

		public bool IsCanceled => (_resultFlags & ResultFlags.Canceled) != 0;

		public bool IsCompleted => (_resultFlags & ResultFlags.Completed) != 0;

		public ReadResult(ReadOnlySequence<byte> buffer, bool isCanceled, bool isCompleted)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			_resultBuffer = buffer;
			_resultFlags = ResultFlags.None;
			if (isCompleted)
			{
				_resultFlags |= ResultFlags.Completed;
			}
			if (isCanceled)
			{
				_resultFlags |= ResultFlags.Canceled;
			}
		}
	}
	[Flags]
	internal enum ResultFlags : byte
	{
		None = 0,
		Canceled = 1,
		Completed = 2
	}
	public static class StreamPipeExtensions
	{
		public static Task CopyToAsync(this Stream source, PipeWriter destination, CancellationToken cancellationToken = default(CancellationToken))
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (destination == null)
			{
				throw new ArgumentNullException("destination");
			}
			if (cancellationToken.IsCancellationRequested)
			{
				return Task.FromCanceled(cancellationToken);
			}
			return destination.CopyFromAsync(source, cancellationToken);
		}
	}
	internal class StreamPipeReader : PipeReader
	{
		internal const int InitialSegmentPoolSize = 4;

		internal const int MaxSegmentPoolSize = 256;

		private readonly int _bufferSize;

		private readonly int _minimumReadThreshold;

		private readonly MemoryPool<byte> _pool;

		private CancellationTokenSource _internalTokenSource;

		private bool _isReaderCompleted;

		private bool _isStreamCompleted;

		private BufferSegment _readHead;

		private int _readIndex;

		private BufferSegment _readTail;

		private long _bufferedBytes;

		private bool _examinedEverything;

		private readonly object _lock = new object();

		private BufferSegmentStack _bufferSegmentPool;

		private readonly bool _leaveOpen;

		public Stream InnerStream { get; }

		private CancellationTokenSource InternalTokenSource
		{
			get
			{
				lock (_lock)
				{
					if (_internalTokenSource == null)
					{
						_internalTokenSource = new CancellationTokenSource();
					}
					return _internalTokenSource;
				}
			}
		}

		public StreamPipeReader(Stream readingStream, StreamPipeReaderOptions options)
		{
			InnerStream = readingStream ?? throw new ArgumentNullException("readingStream");
			if (options == null)
			{
				throw new ArgumentNullException("options");
			}
			_bufferSegmentPool = new BufferSegmentStack(4);
			_minimumReadThreshold = Math.Min(options.MinimumReadSize, options.BufferSize);
			_pool = ((options.Pool == MemoryPool<byte>.Shared) ? null : options.Pool);
			_bufferSize = ((_pool == null) ? options.BufferSize : Math.Min(options.BufferSize, _pool.MaxBufferSize));
			_leaveOpen = options.LeaveOpen;
		}

		public override void AdvanceTo(SequencePosition consumed)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			AdvanceTo(consumed, consumed);
		}

		public override void AdvanceTo(SequencePosition consumed, SequencePosition examined)
		{
			ThrowIfCompleted();
			AdvanceTo((BufferSegment)((SequencePosition)(ref consumed)).GetObject(), ((SequencePosition)(ref consumed)).GetInteger(), (BufferSegment)((SequencePosition)(ref examined)).GetObject(), ((SequencePosition)(ref examined)).GetInteger());
		}

		private void AdvanceTo(BufferSegment consumedSegment, int consumedIndex, BufferSegment examinedSegment, int examinedIndex)
		{
			if (consumedSegment != null && examinedSegment != null)
			{
				if (_readHead == null)
				{
					ThrowHelper.ThrowInvalidOperationException_AdvanceToInvalidCursor();
				}
				BufferSegment bufferSegment = _readHead;
				BufferSegment bufferSegment2 = consumedSegment;
				long length = BufferSegment.GetLength(bufferSegment, _readIndex, consumedSegment, consumedIndex);
				_bufferedBytes -= length;
				_examinedEverything = false;
				if (examinedSegment == _readTail)
				{
					_examinedEverything = examinedIndex == _readTail.End;
				}
				if (_bufferedBytes == 0L)
				{
					bufferSegment2 = null;
					_readHead = null;
					_readTail = null;
					_readIndex = 0;
				}
				else if (consumedIndex == bufferSegment2.Length)
				{
					BufferSegment bufferSegment3 = (_readHead = bufferSegment2.NextSegment);
					_readIndex = 0;
					bufferSegment2 = bufferSegment3;
				}
				else
				{
					_readHead = consumedSegment;
					_readIndex = consumedIndex;
				}
				while (bufferSegment != bufferSegment2)
				{
					BufferSegment nextSegment = bufferSegment.NextSegment;
					bufferSegment.ResetMemory();
					ReturnSegmentUnsynchronized(bufferSegment);
					bufferSegment = nextSegment;
				}
			}
		}

		public override void CancelPendingRead()
		{
			InternalTokenSource.Cancel();
		}

		public override void Complete(Exception? exception = null)
		{
			if (!_isReaderCompleted)
			{
				_isReaderCompleted = true;
				BufferSegment bufferSegment = _readHead;
				while (bufferSegment != null)
				{
					BufferSegment bufferSegment2 = bufferSegment;
					bufferSegment = bufferSegment.NextSegment;
					bufferSegment2.ResetMemory();
				}
				if (!_leaveOpen)
				{
					InnerStream.Dispose();
				}
			}
		}

		public override async ValueTask<ReadResult> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			ThrowIfCompleted();
			CancellationTokenSource tokenSource = InternalTokenSource;
			if (TryReadInternal(tokenSource, out var result))
			{
				return result;
			}
			if (_isStreamCompleted)
			{
				return new ReadResult(default(ReadOnlySequence<byte>), isCanceled: false, isCompleted: true);
			}
			CancellationTokenRegistration cancellationTokenRegistration = default(CancellationTokenRegistration);
			if (cancellationToken.CanBeCanceled)
			{
				cancellationTokenRegistration = CancellationTokenExtensions.UnsafeRegister(cancellationToken, delegate(object state)
				{
					((StreamPipeReader)state).Cancel();
				}, this);
			}
			using (cancellationTokenRegistration)
			{
				bool isCanceled = false;
				try
				{
					AllocateReadTail();
					Memory<byte> buffer = _readTail.AvailableMemory.Slice(_readTail.End);
					int num = await StreamExtensions.ReadAsync(InnerStream, buffer, tokenSource.Token).ConfigureAwait(continueOnCapturedContext: false);
					_readTail.End += num;
					_bufferedBytes += num;
					if (num == 0)
					{
						_isStreamCompleted = true;
					}
				}
				catch (OperationCanceledException)
				{
					ClearCancellationToken();
					if (!tokenSource.IsCancellationRequested || cancellationToken.IsCancellationRequested)
					{
						throw;
					}
					isCanceled = true;
				}
				return new ReadResult(GetCurrentReadOnlySequence(), isCanceled, _isStreamCompleted);
			}
		}

		private void ClearCancellationToken()
		{
			lock (_lock)
			{
				_internalTokenSource = null;
			}
		}

		private void ThrowIfCompleted()
		{
			if (_isReaderCompleted)
			{
				ThrowHelper.ThrowInvalidOperationException_NoReadingAllowed();
			}
		}

		public override bool TryRead(out ReadResult result)
		{
			ThrowIfCompleted();
			return TryReadInternal(InternalTokenSource, out result);
		}

		private bool TryReadInternal(CancellationTokenSource source, out ReadResult result)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			bool isCancellationRequested = source.IsCancellationRequested;
			if (isCancellationRequested || (_bufferedBytes > 0 && (!_examinedEverything || _isStreamCompleted)))
			{
				if (isCancellationRequested)
				{
					ClearCancellationToken();
				}
				ReadOnlySequence<byte> buffer = ((_readHead == null) ? default(ReadOnlySequence<byte>) : GetCurrentReadOnlySequence());
				result = new ReadResult(buffer, isCancellationRequested, _isStreamCompleted);
				return true;
			}
			result = default(ReadResult);
			return false;
		}

		private ReadOnlySequence<byte> GetCurrentReadOnlySequence()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			return new ReadOnlySequence<byte>((ReadOnlySequenceSegment<byte>)_readHead, _readIndex, (ReadOnlySequenceSegment<byte>)_readTail, _readTail.End);
		}

		private void AllocateReadTail()
		{
			if (_readHead == null)
			{
				_readHead = AllocateSegment();
				_readTail = _readHead;
			}
			else if (_readTail.WritableBytes < _minimumReadThreshold)
			{
				BufferSegment bufferSegment = AllocateSegment();
				_readTail.SetNext(bufferSegment);
				_readTail = bufferSegment;
			}
		}

		private BufferSegment AllocateSegment()
		{
			BufferSegment bufferSegment = CreateSegmentUnsynchronized();
			if (_pool == null)
			{
				bufferSegment.SetOwnedMemory(ArrayPool<byte>.Shared.Rent(_bufferSize));
			}
			else
			{
				bufferSegment.SetOwnedMemory(_pool.Rent(_bufferSize));
			}
			return bufferSegment;
		}

		private BufferSegment CreateSegmentUnsynchronized()
		{
			if (_bufferSegmentPool.TryPop(out BufferSegment result))
			{
				return result;
			}
			return new BufferSegment();
		}

		private void ReturnSegmentUnsynchronized(BufferSegment segment)
		{
			if (_bufferSegmentPool.Count < 256)
			{
				_bufferSegmentPool.Push(segment);
			}
		}

		private void Cancel()
		{
			InternalTokenSource.Cancel();
		}
	}
	public class StreamPipeReaderOptions
	{
		private const int DefaultBufferSize = 4096;

		private const int DefaultMinimumReadSize = 1024;

		internal static readonly StreamPipeReaderOptions s_default = new StreamPipeReaderOptions();

		public int BufferSize { get; }

		public int MinimumReadSize { get; }

		public MemoryPool<byte> Pool { get; }

		public bool LeaveOpen { get; }

		public StreamPipeReaderOptions(MemoryPool<byte>? pool = null, int bufferSize = -1, int minimumReadSize = -1, bool leaveOpen = false)
		{
			Pool = pool ?? MemoryPool<byte>.Shared;
			int num;
			if (bufferSize != -1)
			{
				if (bufferSize <= 0)
				{
					throw new ArgumentOutOfRangeException("bufferSize");
				}
				num = bufferSize;
			}
			else
			{
				num = 4096;
			}
			BufferSize = num;
			int num2;
			if (minimumReadSize != -1)
			{
				if (minimumReadSize <= 0)
				{
					throw new ArgumentOutOfRangeException("minimumReadSize");
				}
				num2 = minimumReadSize;
			}
			else
			{
				num2 = 1024;
			}
			MinimumReadSize = num2;
			LeaveOpen = leaveOpen;
		}
	}
	internal class StreamPipeWriter : PipeWriter
	{
		internal const int InitialSegmentPoolSize = 4;

		internal const int MaxSegmentPoolSize = 256;

		private readonly int _minimumBufferSize;

		private BufferSegment _head;

		private BufferSegment _tail;

		private Memory<byte> _tailMemory;

		private int _tailBytesBuffered;

		private int _bytesBuffered;

		private readonly MemoryPool<byte> _pool;

		private CancellationTokenSource _internalTokenSource;

		private bool _isCompleted;

		private readonly object _lockObject = new object();

		private BufferSegmentStack _bufferSegmentPool;

		private readonly bool _leaveOpen;

		private CancellationTokenSource InternalTokenSource
		{
			get
			{
				lock (_lockObject)
				{
					if (_internalTokenSource == null)
					{
						_internalTokenSource = new CancellationTokenSource();
					}
					return _internalTokenSource;
				}
			}
		}

		public Stream InnerStream { get; }

		public StreamPipeWriter(Stream writingStream, StreamPipeWriterOptions options)
		{
			InnerStream = writingStream ?? throw new ArgumentNullException("writingStream");
			if (options == null)
			{
				throw new ArgumentNullException("options");
			}
			_minimumBufferSize = options.MinimumBufferSize;
			_pool = ((options.Pool == MemoryPool<byte>.Shared) ? null : options.Pool);
			_bufferSegmentPool = new BufferSegmentStack(4);
			_leaveOpen = options.LeaveOpen;
		}

		public override void Advance(int bytes)
		{
			if ((uint)bytes > (uint)_tailMemory.Length)
			{
				ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes);
			}
			_tailBytesBuffered += bytes;
			_bytesBuffered += bytes;
			_tailMemory = _tailMemory.Slice(bytes);
		}

		public override Memory<byte> GetMemory(int sizeHint = 0)
		{
			if (_isCompleted)
			{
				ThrowHelper.ThrowInvalidOperationException_NoWritingAllowed();
			}
			if (sizeHint < 0)
			{
				ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.sizeHint);
			}
			AllocateMemory(sizeHint);
			return _tailMemory;
		}

		public override Span<byte> GetSpan(int sizeHint = 0)
		{
			if (_isCompleted)
			{
				ThrowHelper.ThrowInvalidOperationException_NoWritingAllowed();
			}
			if (sizeHint < 0)
			{
				ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.sizeHint);
			}
			AllocateMemory(sizeHint);
			return _tailMemory.Span;
		}

		private void AllocateMemory(int sizeHint)
		{
			if (_head == null)
			{
				BufferSegment tail = AllocateSegment(sizeHint);
				_head = (_tail = tail);
				_tailBytesBuffered = 0;
				return;
			}
			int length = _tailMemory.Length;
			if (length == 0 || length < sizeHint)
			{
				if (_tailBytesBuffered > 0)
				{
					_tail.End += _tailBytesBuffered;
					_tailBytesBuffered = 0;
				}
				BufferSegment bufferSegment = AllocateSegment(sizeHint);
				_tail.SetNext(bufferSegment);
				_tail = bufferSegment;
			}
		}

		private BufferSegment AllocateSegment(int sizeHint)
		{
			BufferSegment bufferSegment = CreateSegmentUnsynchronized();
			if (_pool == null || sizeHint > _pool.MaxBufferSize)
			{
				int segmentSize = GetSegmentSize(sizeHint);
				bufferSegment.SetOwnedMemory(ArrayPool<byte>.Shared.Rent(segmentSize));
			}
			else
			{
				bufferSegment.SetOwnedMemory(_pool.Rent(GetSegmentSize(sizeHint, _pool.MaxBufferSize)));
			}
			_tailMemory = bufferSegment.AvailableMemory;
			return bufferSegment;
		}

		private int GetSegmentSize(int sizeHint, int maxBufferSize = int.MaxValue)
		{
			sizeHint = Math.Max(_minimumBufferSize, sizeHint);
			return Math.Min(maxBufferSize, sizeHint);
		}

		private BufferSegment CreateSegmentUnsynchronized()
		{
			if (_bufferSegmentPool.TryPop(out BufferSegment result))
			{
				return result;
			}
			return new BufferSegment();
		}

		private void ReturnSegmentUnsynchronized(BufferSegment segment)
		{
			if (_bufferSegmentPool.Count < 256)
			{
				_bufferSegmentPool.Push(segment);
			}
		}

		public override void CancelPendingFlush()
		{
			Cancel();
		}

		public override void Complete(Exception? exception = null)
		{
			if (!_isCompleted)
			{
				_isCompleted = true;
				FlushInternal(exception == null);
				_internalTokenSource?.Dispose();
				if (!_leaveOpen)
				{
					InnerStream.Dispose();
				}
			}
		}

		public override async ValueTask CompleteAsync(Exception? exception = null)
		{
			if (!_isCompleted)
			{
				_isCompleted = true;
				await FlushAsyncInternal(exception == null).ConfigureAwait(continueOnCapturedContext: false);
				_internalTokenSource?.Dispose();
				if (!_leaveOpen)
				{
					InnerStream.Dispose();
				}
			}
		}

		public override ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			if (_bytesBuffered == 0)
			{
				return new ValueTask<FlushResult>(new FlushResult(isCanceled: false, isCompleted: false));
			}
			return FlushAsyncInternal(writeToStream: true, cancellationToken);
		}

		private void Cancel()
		{
			InternalTokenSource.Cancel();
		}

		private async ValueTask<FlushResult> FlushAsyncInternal(bool writeToStream, CancellationToken cancellationToken = default(CancellationToken))
		{
			CancellationTokenRegistration cancellationTokenRegistration = default(CancellationTokenRegistration);
			if (cancellationToken.CanBeCanceled)
			{
				cancellationTokenRegistration = CancellationTokenExtensions.UnsafeRegister(cancellationToken, delegate(object state)
				{
					((StreamPipeWriter)state).Cancel();
				}, this);
			}
			if (_tailBytesBuffered > 0)
			{
				_tail.End += _tailBytesBuffered;
				_tailBytesBuffered = 0;
			}
			using (cancellationTokenRegistration)
			{
				CancellationToken localToken = InternalTokenSource.Token;
				try
				{
					BufferSegment segment = _head;
					while (segment != null)
					{
						BufferSegment returnSegment = segment;
						segment = segment.NextSegment;
						if (returnSegment.Length > 0 && writeToStream)
						{
							await StreamExtensions.WriteAsync(InnerStream, ((ReadOnlySequenceSegment<byte>)returnSegment).Memory, localToken).ConfigureAwait(continueOnCapturedContext: false);
						}
						returnSegment.ResetMemory();
						ReturnSegmentUnsynchronized(returnSegment);
						_head = segment;
					}
					if (_bytesBuffered > 0 && writeToStream)
					{
						await InnerStream.FlushAsync(localToken).ConfigureAwait(continueOnCapturedContext: false);
					}
					_head = null;
					_tail = null;
					_bytesBuffered = 0;
					return new FlushResult(isCanceled: false, isCompleted: false);
				}
				catch (OperationCanceledException)
				{
					lock (_lockObject)
					{
						_internalTokenSource = null;
					}
					if (localToken.IsCancellationRequested && !cancellationToken.IsCancellationRequested)
					{
						return new FlushResult(isCanceled: true, isCompleted: false);
					}
					throw;
				}
			}
		}

		private void FlushInternal(bool writeToStream)
		{
			if (_tailBytesBuffered > 0)
			{
				_tail.End += _tailBytesBuffered;
				_tailBytesBuffered = 0;
			}
			BufferSegment bufferSegment = _head;
			while (bufferSegment != null)
			{
				BufferSegment bufferSegment2 = bufferSegment;
				bufferSegment = bufferSegment.NextSegment;
				if (bufferSegment2.Length > 0 && writeToStream)
				{
					InnerStream.Write(((ReadOnlySequenceSegment<byte>)bufferSegment2).Memory);
				}
				bufferSegment2.ResetMemory();
				ReturnSegmentUnsynchronized(bufferSegment2);
				_head = bufferSegment;
			}
			if (_bytesBuffered > 0 && writeToStream)
			{
				InnerStream.Flush();
			}
			_head = null;
			_tail = null;
			_bytesBuffered = 0;
		}
	}
	public class StreamPipeWriterOptions
	{
		private const int DefaultMinimumBufferSize = 4096;

		internal static StreamPipeWriterOptions s_default = new StreamPipeWriterOptions();

		public int MinimumBufferSize { get; }

		public MemoryPool<byte> Pool { get; }

		public bool LeaveOpen { get; }

		public StreamPipeWriterOptions(MemoryPool<byte>? pool = null, int minimumBufferSize = -1, bool leaveOpen = false)
		{
			Pool = pool ?? MemoryPool<byte>.Shared;
			int num;
			if (minimumBufferSize != -1)
			{
				if (minimumBufferSize <= 0)
				{
					throw new ArgumentOutOfRangeException("minimumBufferSize");
				}
				num = minimumBufferSize;
			}
			else
			{
				num = 4096;
			}
			MinimumBufferSize = num;
			LeaveOpen = leaveOpen;
		}
	}
	internal static class ThrowHelper
	{
		[DoesNotReturn]
		internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument)
		{
			throw CreateArgumentOutOfRangeException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException(ExceptionArgument argument)
		{
			return new ArgumentOutOfRangeException(argument.ToString());
		}

		[DoesNotReturn]
		internal static void ThrowArgumentNullException(ExceptionArgument argument)
		{
			throw CreateArgumentNullException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentNullException(ExceptionArgument argument)
		{
			return new ArgumentNullException(argument.ToString());
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_AlreadyReading()
		{
			throw CreateInvalidOperationException_AlreadyReading();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateInvalidOperationException_AlreadyReading()
		{
			return new InvalidOperationException(System.SR.ReadingIsInProgress);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_NoReadToComplete()
		{
			throw CreateInvalidOperationException_NoReadToComplete();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateInvalidOperationException_NoReadToComplete()
		{
			return new InvalidOperationException(System.SR.NoReadingOperationToComplete);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_NoConcurrentOperation()
		{
			throw CreateInvalidOperationException_NoConcurrentOperation();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateInvalidOperationException_NoConcurrentOperation()
		{
			return new InvalidOperationException(System.SR.ConcurrentOperationsNotSupported);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_GetResultNotCompleted()
		{
			throw CreateInvalidOperationException_GetResultNotCompleted();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateInvalidOperationException_GetResultNotCompleted()
		{
			return new InvalidOperationException(System.SR.GetResultBeforeCompleted);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_NoWritingAllowed()
		{
			throw CreateInvalidOperationException_NoWritingAllowed();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateInvalidOperationException_NoWritingAllowed()
		{
			return new InvalidOperationException(System.SR.WritingAfterCompleted);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_NoReadingAllowed()
		{
			throw CreateInvalidOperationException_NoReadingAllowed();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateInvalidOperationException_NoReadingAllowed()
		{
			return new InvalidOperationException(System.SR.ReadingAfterCompleted);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_InvalidExaminedPosition()
		{
			throw CreateInvalidOperationException_InvalidExaminedPosition();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateInvalidOperationException_InvalidExaminedPosition()
		{
			return new InvalidOperationException(System.SR.InvalidExaminedPosition);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_InvalidExaminedOrConsumedPosition()
		{
			throw CreateInvalidOperationException_InvalidExaminedOrConsumedPosition();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateInvalidOperationException_InvalidExaminedOrConsumedPosition()
		{
			return new InvalidOperationException(System.SR.InvalidExaminedOrConsumedPosition);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_AdvanceToInvalidCursor()
		{
			throw CreateInvalidOperationException_AdvanceToInvalidCursor();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateInvalidOperationException_AdvanceToInvalidCursor()
		{
			return new InvalidOperationException(System.SR.AdvanceToInvalidCursor);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ResetIncompleteReaderWriter()
		{
			throw CreateInvalidOperationException_ResetIncompleteReaderWriter();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateInvalidOperationException_ResetIncompleteReaderWriter()
		{
			return new InvalidOperationException(System.SR.ReaderAndWriterHasToBeCompleted);
		}

		[DoesNotReturn]
		public static void ThrowOperationCanceledException_ReadCanceled()
		{
			throw CreateOperationCanceledException_ReadCanceled();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateOperationCanceledException_ReadCanceled()
		{
			return new OperationCanceledException(System.SR.ReadCanceledOnPipeReader);
		}

		[DoesNotReturn]
		public static void ThrowOperationCanceledException_FlushCanceled()
		{
			throw CreateOperationCanceledException_FlushCanceled();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateOperationCanceledException_FlushCanceled()
		{
			return new OperationCanceledException(System.SR.FlushCanceledOnPipeWriter);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_InvalidZeroByteRead()
		{
			throw CreateInvalidOperationException_InvalidZeroByteRead();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static Exception CreateInvalidOperationException_InvalidZeroByteRead()
		{
			return new InvalidOperationException(System.SR.InvalidZeroByteRead);
		}
	}
	internal enum ExceptionArgument
	{
		minimumSize,
		bytes,
		callback,
		options,
		pauseWriterThreshold,
		resumeWriterThreshold,
		sizeHint
	}
	internal static class StreamExtensions
	{
		public static ValueTask<int> ReadAsync(this Stream stream, Memory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
		{
			if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)buffer, out ArraySegment<byte> segment))
			{
				return new ValueTask<int>(stream.ReadAsync(segment.Array, segment.Offset, segment.Count, cancellationToken));
			}
			byte[] array = ArrayPool<byte>.Shared.Rent(buffer.Length);
			return FinishReadAsync(stream.ReadAsync(array, 0, buffer.Length, cancellationToken), array, buffer);
			static async ValueTask<int> FinishReadAsync(Task<int> readTask, byte[] localBuffer, Memory<byte> localDestination)
			{
				try
				{
					int num = await readTask.ConfigureAwait(continueOnCapturedContext: false);
					new Span<byte>(localBuffer, 0, num).CopyTo(localDestination.Span);
					return num;
				}
				finally
				{
					ArrayPool<byte>.Shared.Return(localBuffer);
				}
			}
		}

		public static void Write(this Stream stream, ReadOnlyMemory<byte> buffer)
		{
			if (MemoryMarshal.TryGetArray(buffer, out var segment))
			{
				stream.Write(segment.Array, segment.Offset, segment.Count);
				return;
			}
			byte[] array = ArrayPool<byte>.Shared.Rent(buffer.Length);
			try
			{
				buffer.Span.CopyTo(array);
				stream.Write(array, 0, buffer.Length);
			}
			finally
			{
				ArrayPool<byte>.Shared.Return(array);
			}
		}

		public static ValueTask WriteAsync(this Stream stream, ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
		{
			if (MemoryMarshal.TryGetArray(buffer, out var segment))
			{
				return new ValueTask(stream.WriteAsync(segment.Array, segment.Offset, segment.Count, cancellationToken));
			}
			byte[] array = ArrayPool<byte>.Shared.Rent(buffer.Length);
			buffer.Span.CopyTo(array);
			return new ValueTask(FinishWriteAsync(stream.WriteAsync(array, 0, buffer.Length, cancellationToken), array));
		}

		private static async Task FinishWriteAsync(Task writeTask, byte[] localBuffer)
		{
			try
			{
				await writeTask.ConfigureAwait(continueOnCapturedContext: false);
			}
			finally
			{
				ArrayPool<byte>.Shared.Return(localBuffer);
			}
		}
	}
	internal sealed class ThreadPoolScheduler : PipeScheduler
	{
		public override void Schedule(Action<object> action, object state)
		{
			System.Threading.ThreadPool.QueueUserWorkItem(delegate(object s)
			{
				Tuple<Action<object>, object> tuple = (Tuple<Action<object>, object>)s;
				tuple.Item1(tuple.Item2);
			}, Tuple.Create(action, state));
		}
	}
}
namespace System.Threading
{
	internal static class CancellationTokenExtensions
	{
		internal static CancellationTokenRegistration UnsafeRegister(this CancellationToken cancellationToken, Action<object> callback, object state)
		{
			return cancellationToken.Register(callback, state);
		}
	}
}
namespace System.Threading.Tasks
{
	internal static class TaskToApm
	{
		internal sealed class TaskAsyncResult : IAsyncResult
		{
			internal readonly Task _task;

			private readonly AsyncCallback _callback;

			public object? AsyncState { get; }

			public bool CompletedSynchronously { get; }

			public bool IsCompleted => _task.IsCompleted;

			public WaitHandle AsyncWaitHandle => ((IAsyncResult)_task).AsyncWaitHandle;

			internal TaskAsyncResult(Task task, object? state, AsyncCallback? callback)
			{
				_task = task;
				AsyncState = state;
				if (task.IsCompleted)
				{
					CompletedSynchronously = true;
					callback?.Invoke(this);
				}
				else if (callback != null)
				{
					_callback = callback;
					_task.ConfigureAwait(continueOnCapturedContext: false).GetAwaiter().OnCompleted(InvokeCallback);
				}
			}

			private void InvokeCallback()
			{
				_callback(this);
			}
		}

		public static IAsyncResult Begin(Task task, AsyncCallback? callback, object? state)
		{
			return new TaskAsyncResult(task, state, callback);
		}

		public static void End(IAsyncResult asyncResult)
		{
			if (asyncResult is TaskAsyncResult taskAsyncResult)
			{
				taskAsyncResult._task.GetAwaiter().GetResult();
			}
			else
			{
				ThrowArgumentException(asyncResult);
			}
		}

		public static TResult End<TResult>(IAsyncResult asyncResult)
		{
			if (asyncResult is TaskAsyncResult taskAsyncResult && taskAsyncResult._task is Task<TResult> task)
			{
				return task.GetAwaiter().GetResult();
			}
			ThrowArgumentException(asyncResult);
			return default(TResult);
		}

		[DoesNotReturn]
		private static void ThrowArgumentException(IAsyncResult asyncResult)
		{
			throw (asyncResult == null) ? new ArgumentNullException("asyncResult") : new ArgumentException(null, "asyncResult");
		}
	}
}

System.Memory.dll

Decompiled 2 weeks ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Buffers.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FxResources.System.Memory;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Memory")]
[assembly: AssemblyDescription("System.Memory")]
[assembly: AssemblyDefaultAlias("System.Memory")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.31308.01")]
[assembly: AssemblyInformationalVersion("4.6.31308.01 @BuiltBy: cloudtest-841353dfc000000 @Branch: release/2.1-MSRC @SrcCode: https://github.com/dotnet/corefx/tree/32b491939fbd125f304031c35038b1e14b4e3958")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.1.2")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsByRefLikeAttribute : Attribute
	{
	}
}
namespace FxResources.System.Memory
{
	internal static class SR
	{
	}
}
namespace System
{
	public readonly struct SequencePosition : IEquatable<SequencePosition>
	{
		private readonly object _object;

		private readonly int _integer;

		public SequencePosition(object @object, int integer)
		{
			_object = @object;
			_integer = integer;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public object GetObject()
		{
			return _object;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public int GetInteger()
		{
			return _integer;
		}

		public bool Equals(SequencePosition other)
		{
			if (_integer == other._integer)
			{
				return object.Equals(_object, other._object);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is SequencePosition other)
			{
				return Equals(other);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			return HashHelpers.Combine(_object?.GetHashCode() ?? 0, _integer);
		}
	}
	internal static class ThrowHelper
	{
		internal static void ThrowArgumentNullException(System.ExceptionArgument argument)
		{
			throw CreateArgumentNullException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentNullException(System.ExceptionArgument argument)
		{
			return new ArgumentNullException(argument.ToString());
		}

		internal static void ThrowArrayTypeMismatchException()
		{
			throw CreateArrayTypeMismatchException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArrayTypeMismatchException()
		{
			return new ArrayTypeMismatchException();
		}

		internal static void ThrowArgumentException_InvalidTypeWithPointersNotSupported(Type type)
		{
			throw CreateArgumentException_InvalidTypeWithPointersNotSupported(type);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_InvalidTypeWithPointersNotSupported(Type type)
		{
			return new ArgumentException(System.SR.Format(System.SR.Argument_InvalidTypeWithPointersNotSupported, type));
		}

		internal static void ThrowArgumentException_DestinationTooShort()
		{
			throw CreateArgumentException_DestinationTooShort();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_DestinationTooShort()
		{
			return new ArgumentException(System.SR.Argument_DestinationTooShort);
		}

		internal static void ThrowIndexOutOfRangeException()
		{
			throw CreateIndexOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateIndexOutOfRangeException()
		{
			return new IndexOutOfRangeException();
		}

		internal static void ThrowArgumentOutOfRangeException()
		{
			throw CreateArgumentOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException()
		{
			return new ArgumentOutOfRangeException();
		}

		internal static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			throw CreateArgumentOutOfRangeException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			return new ArgumentOutOfRangeException(argument.ToString());
		}

		internal static void ThrowArgumentOutOfRangeException_PrecisionTooLarge()
		{
			throw CreateArgumentOutOfRangeException_PrecisionTooLarge();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_PrecisionTooLarge()
		{
			return new ArgumentOutOfRangeException("precision", System.SR.Format(System.SR.Argument_PrecisionTooLarge, (byte)99));
		}

		internal static void ThrowArgumentOutOfRangeException_SymbolDoesNotFit()
		{
			throw CreateArgumentOutOfRangeException_SymbolDoesNotFit();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_SymbolDoesNotFit()
		{
			return new ArgumentOutOfRangeException("symbol", System.SR.Argument_BadFormatSpecifier);
		}

		internal static void ThrowInvalidOperationException()
		{
			throw CreateInvalidOperationException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException()
		{
			return new InvalidOperationException();
		}

		internal static void ThrowInvalidOperationException_OutstandingReferences()
		{
			throw CreateInvalidOperationException_OutstandingReferences();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_OutstandingReferences()
		{
			return new InvalidOperationException(System.SR.OutstandingReferences);
		}

		internal static void ThrowInvalidOperationException_UnexpectedSegmentType()
		{
			throw CreateInvalidOperationException_UnexpectedSegmentType();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_UnexpectedSegmentType()
		{
			return new InvalidOperationException(System.SR.UnexpectedSegmentType);
		}

		internal static void ThrowInvalidOperationException_EndPositionNotReached()
		{
			throw CreateInvalidOperationException_EndPositionNotReached();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_EndPositionNotReached()
		{
			return new InvalidOperationException(System.SR.EndPositionNotReached);
		}

		internal static void ThrowArgumentOutOfRangeException_PositionOutOfRange()
		{
			throw CreateArgumentOutOfRangeException_PositionOutOfRange();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_PositionOutOfRange()
		{
			return new ArgumentOutOfRangeException("position");
		}

		internal static void ThrowArgumentOutOfRangeException_OffsetOutOfRange()
		{
			throw CreateArgumentOutOfRangeException_OffsetOutOfRange();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_OffsetOutOfRange()
		{
			return new ArgumentOutOfRangeException("offset");
		}

		internal static void ThrowObjectDisposedException_ArrayMemoryPoolBuffer()
		{
			throw CreateObjectDisposedException_ArrayMemoryPoolBuffer();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateObjectDisposedException_ArrayMemoryPoolBuffer()
		{
			return new ObjectDisposedException("ArrayMemoryPoolBuffer");
		}

		internal static void ThrowFormatException_BadFormatSpecifier()
		{
			throw CreateFormatException_BadFormatSpecifier();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateFormatException_BadFormatSpecifier()
		{
			return new FormatException(System.SR.Argument_BadFormatSpecifier);
		}

		internal static void ThrowArgumentException_OverlapAlignmentMismatch()
		{
			throw CreateArgumentException_OverlapAlignmentMismatch();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_OverlapAlignmentMismatch()
		{
			return new ArgumentException(System.SR.Argument_OverlapAlignmentMismatch);
		}

		internal static void ThrowNotSupportedException()
		{
			throw CreateThrowNotSupportedException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateThrowNotSupportedException()
		{
			return new NotSupportedException();
		}

		public static bool TryFormatThrowFormatException(out int bytesWritten)
		{
			bytesWritten = 0;
			ThrowFormatException_BadFormatSpecifier();
			return false;
		}

		public static bool TryParseThrowFormatException<T>(out T value, out int bytesConsumed)
		{
			value = default(T);
			bytesConsumed = 0;
			ThrowFormatException_BadFormatSpecifier();
			return false;
		}

		public static void ThrowArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
		{
			throw CreateArgumentValidationException(startSegment, startIndex, endSegment);
		}

		private static Exception CreateArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
		{
			if (startSegment == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.startSegment);
			}
			if (endSegment == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.endSegment);
			}
			if (startSegment != endSegment && startSegment.RunningIndex > endSegment.RunningIndex)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.endSegment);
			}
			if ((uint)startSegment.Memory.Length < (uint)startIndex)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.startIndex);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.endIndex);
		}

		public static void ThrowArgumentValidationException(Array array, int start)
		{
			throw CreateArgumentValidationException(array, start);
		}

		private static Exception CreateArgumentValidationException(Array array, int start)
		{
			if (array == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.array);
			}
			if ((uint)start > (uint)array.Length)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
		}

		public static void ThrowStartOrEndArgumentValidationException(long start)
		{
			throw CreateStartOrEndArgumentValidationException(start);
		}

		private static Exception CreateStartOrEndArgumentValidationException(long start)
		{
			if (start < 0)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
		}
	}
	internal enum ExceptionArgument
	{
		length,
		start,
		minimumBufferSize,
		elementIndex,
		comparable,
		comparer,
		destination,
		offset,
		startSegment,
		endSegment,
		startIndex,
		endIndex,
		array,
		culture,
		manager
	}
	internal static class DecimalDecCalc
	{
		private static uint D32DivMod1E9(uint hi32, ref uint lo32)
		{
			ulong num = ((ulong)hi32 << 32) | lo32;
			lo32 = (uint)(num / 1000000000);
			return (uint)(num % 1000000000);
		}

		internal static uint DecDivMod1E9(ref MutableDecimal value)
		{
			return D32DivMod1E9(D32DivMod1E9(D32DivMod1E9(0u, ref value.High), ref value.Mid), ref value.Low);
		}

		internal static void DecAddInt32(ref MutableDecimal value, uint i)
		{
			if (D32AddCarry(ref value.Low, i) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
		}

		private static bool D32AddCarry(ref uint value, uint i)
		{
			uint num = value;
			uint num2 = (value = num + i);
			if (num2 >= num)
			{
				return num2 < i;
			}
			return true;
		}

		internal static void DecMul10(ref MutableDecimal value)
		{
			MutableDecimal d = value;
			DecShiftLeft(ref value);
			DecShiftLeft(ref value);
			DecAdd(ref value, d);
			DecShiftLeft(ref value);
		}

		private static void DecShiftLeft(ref MutableDecimal value)
		{
			uint num = (((value.Low & 0x80000000u) != 0) ? 1u : 0u);
			uint num2 = (((value.Mid & 0x80000000u) != 0) ? 1u : 0u);
			value.Low <<= 1;
			value.Mid = (value.Mid << 1) | num;
			value.High = (value.High << 1) | num2;
		}

		private static void DecAdd(ref MutableDecimal value, MutableDecimal d)
		{
			if (D32AddCarry(ref value.Low, d.Low) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
			if (D32AddCarry(ref value.Mid, d.Mid))
			{
				D32AddCarry(ref value.High, 1u);
			}
			D32AddCarry(ref value.High, d.High);
		}
	}
	internal static class Number
	{
		private static class DoubleHelper
		{
			public unsafe static uint Exponent(double d)
			{
				return (*(uint*)((byte*)(&d) + 4) >> 20) & 0x7FFu;
			}

			public unsafe static ulong Mantissa(double d)
			{
				return *(uint*)(&d) | ((ulong)(uint)(*(int*)((byte*)(&d) + 4) & 0xFFFFF) << 32);
			}

			public unsafe static bool Sign(double d)
			{
				return *(uint*)((byte*)(&d) + 4) >> 31 != 0;
			}
		}

		internal const int DECIMAL_PRECISION = 29;

		private static readonly ulong[] s_rgval64Power10 = new ulong[30]
		{
			11529215046068469760uL, 14411518807585587200uL, 18014398509481984000uL, 11258999068426240000uL, 14073748835532800000uL, 17592186044416000000uL, 10995116277760000000uL, 13743895347200000000uL, 17179869184000000000uL, 10737418240000000000uL,
			13421772800000000000uL, 16777216000000000000uL, 10485760000000000000uL, 13107200000000000000uL, 16384000000000000000uL, 14757395258967641293uL, 11805916207174113035uL, 9444732965739290428uL, 15111572745182864686uL, 12089258196146291749uL,
			9671406556917033399uL, 15474250491067253438uL, 12379400392853802751uL, 9903520314283042201uL, 15845632502852867522uL, 12676506002282294018uL, 10141204801825835215uL, 16225927682921336344uL, 12980742146337069075uL, 10384593717069655260uL
		};

		private static readonly sbyte[] s_rgexp64Power10 = new sbyte[15]
		{
			4, 7, 10, 14, 17, 20, 24, 27, 30, 34,
			37, 40, 44, 47, 50
		};

		private static readonly ulong[] s_rgval64Power10By16 = new ulong[42]
		{
			10240000000000000000uL, 11368683772161602974uL, 12621774483536188886uL, 14012984643248170708uL, 15557538194652854266uL, 17272337110188889248uL, 9588073174409622172uL, 10644899600020376798uL, 11818212630765741798uL, 13120851772591970216uL,
			14567071740625403792uL, 16172698447808779622uL, 17955302187076837696uL, 9967194951097567532uL, 11065809325636130658uL, 12285516299433008778uL, 13639663065038175358uL, 15143067982934716296uL, 16812182738118149112uL, 9332636185032188787uL,
			10361307573072618722uL, 16615349947311448416uL, 14965776766268445891uL, 13479973333575319909uL, 12141680576410806707uL, 10936253623915059637uL, 9850501549098619819uL, 17745086042373215136uL, 15983352577617880260uL, 14396524142538228461uL,
			12967236152753103031uL, 11679847981112819795uL, 10520271803096747049uL, 9475818434452569218uL, 17070116948172427008uL, 15375394465392026135uL, 13848924157002783096uL, 12474001934591998882uL, 11235582092889474480uL, 10120112665365530972uL,
			18230774251475056952uL, 16420821625123739930uL
		};

		private static readonly short[] s_rgexp64Power10By16 = new short[21]
		{
			54, 107, 160, 213, 266, 319, 373, 426, 479, 532,
			585, 638, 691, 745, 798, 851, 904, 957, 1010, 1064,
			1117
		};

		public static void RoundNumber(ref NumberBuffer number, int pos)
		{
			Span<byte> digits = number.Digits;
			int i;
			for (i = 0; i < pos && digits[i] != 0; i++)
			{
			}
			if (i == pos && digits[i] >= 53)
			{
				while (i > 0 && digits[i - 1] == 57)
				{
					i--;
				}
				if (i > 0)
				{
					digits[i - 1]++;
				}
				else
				{
					number.Scale++;
					digits[0] = 49;
					i = 1;
				}
			}
			else
			{
				while (i > 0 && digits[i - 1] == 48)
				{
					i--;
				}
			}
			if (i == 0)
			{
				number.Scale = 0;
				number.IsNegative = false;
			}
			digits[i] = 0;
		}

		internal static bool NumberBufferToDouble(ref NumberBuffer number, out double value)
		{
			double num = NumberToDouble(ref number);
			uint num2 = DoubleHelper.Exponent(num);
			ulong num3 = DoubleHelper.Mantissa(num);
			switch (num2)
			{
			case 2047u:
				value = 0.0;
				return false;
			case 0u:
				if (num3 == 0L)
				{
					num = 0.0;
				}
				break;
			}
			value = num;
			return true;
		}

		public unsafe static bool NumberBufferToDecimal(ref NumberBuffer number, ref decimal value)
		{
			MutableDecimal value2 = default(MutableDecimal);
			byte* ptr = number.UnsafeDigits;
			int num = number.Scale;
			if (*ptr == 0)
			{
				if (num > 0)
				{
					num = 0;
				}
			}
			else
			{
				if (num > 29)
				{
					return false;
				}
				while ((num > 0 || (*ptr != 0 && num > -28)) && (value2.High < 429496729 || (value2.High == 429496729 && (value2.Mid < 2576980377u || (value2.Mid == 2576980377u && (value2.Low < 2576980377u || (value2.Low == 2576980377u && *ptr <= 53)))))))
				{
					DecimalDecCalc.DecMul10(ref value2);
					if (*ptr != 0)
					{
						DecimalDecCalc.DecAddInt32(ref value2, (uint)(*(ptr++) - 48));
					}
					num--;
				}
				if (*(ptr++) >= 53)
				{
					bool flag = true;
					if (*(ptr - 1) == 53 && *(ptr - 2) % 2 == 0)
					{
						int num2 = 20;
						while (*ptr == 48 && num2 != 0)
						{
							ptr++;
							num2--;
						}
						if (*ptr == 0 || num2 == 0)
						{
							flag = false;
						}
					}
					if (flag)
					{
						DecimalDecCalc.DecAddInt32(ref value2, 1u);
						if ((value2.High | value2.Mid | value2.Low) == 0)
						{
							value2.High = 429496729u;
							value2.Mid = 2576980377u;
							value2.Low = 2576980378u;
							num++;
						}
					}
				}
			}
			if (num > 0)
			{
				return false;
			}
			if (num <= -29)
			{
				value2.High = 0u;
				value2.Low = 0u;
				value2.Mid = 0u;
				value2.Scale = 28;
			}
			else
			{
				value2.Scale = -num;
			}
			value2.IsNegative = number.IsNegative;
			value = System.Runtime.CompilerServices.Unsafe.As<MutableDecimal, decimal>(ref value2);
			return true;
		}

		public static void DecimalToNumber(decimal value, ref NumberBuffer number)
		{
			ref MutableDecimal reference = ref System.Runtime.CompilerServices.Unsafe.As<decimal, MutableDecimal>(ref value);
			Span<byte> digits = number.Digits;
			number.IsNegative = reference.IsNegative;
			int num = 29;
			while ((reference.Mid != 0) | (reference.High != 0))
			{
				uint num2 = DecimalDecCalc.DecDivMod1E9(ref reference);
				for (int i = 0; i < 9; i++)
				{
					digits[--num] = (byte)(num2 % 10 + 48);
					num2 /= 10;
				}
			}
			for (uint num3 = reference.Low; num3 != 0; num3 /= 10)
			{
				digits[--num] = (byte)(num3 % 10 + 48);
			}
			int num4 = 29 - num;
			number.Scale = num4 - reference.Scale;
			Span<byte> digits2 = number.Digits;
			int index = 0;
			while (--num4 >= 0)
			{
				digits2[index++] = digits[num++];
			}
			digits2[index] = 0;
		}

		private static uint DigitsToInt(ReadOnlySpan<byte> digits, int count)
		{
			uint value;
			int bytesConsumed;
			bool flag = Utf8Parser.TryParse(digits.Slice(0, count), out value, out bytesConsumed, 'D');
			return value;
		}

		private static ulong Mul32x32To64(uint a, uint b)
		{
			return (ulong)a * (ulong)b;
		}

		private static ulong Mul64Lossy(ulong a, ulong b, ref int pexp)
		{
			ulong num = Mul32x32To64((uint)(a >> 32), (uint)(b >> 32)) + (Mul32x32To64((uint)(a >> 32), (uint)b) >> 32) + (Mul32x32To64((uint)a, (uint)(b >> 32)) >> 32);
			if ((num & 0x8000000000000000uL) == 0L)
			{
				num <<= 1;
				pexp--;
			}
			return num;
		}

		private static int abs(int value)
		{
			if (value < 0)
			{
				return -value;
			}
			return value;
		}

		private unsafe static double NumberToDouble(ref NumberBuffer number)
		{
			ReadOnlySpan<byte> digits = number.Digits;
			int i = 0;
			int numDigits = number.NumDigits;
			int num = numDigits;
			for (; digits[i] == 48; i++)
			{
				num--;
			}
			if (num == 0)
			{
				return 0.0;
			}
			int num2 = Math.Min(num, 9);
			num -= num2;
			ulong num3 = DigitsToInt(digits, num2);
			if (num > 0)
			{
				num2 = Math.Min(num, 9);
				num -= num2;
				uint b = (uint)(s_rgval64Power10[num2 - 1] >> 64 - s_rgexp64Power10[num2 - 1]);
				num3 = Mul32x32To64((uint)num3, b) + DigitsToInt(digits.Slice(9), num2);
			}
			int num4 = number.Scale - (numDigits - num);
			int num5 = abs(num4);
			if (num5 >= 352)
			{
				ulong num6 = ((num4 > 0) ? 9218868437227405312uL : 0);
				if (number.IsNegative)
				{
					num6 |= 0x8000000000000000uL;
				}
				return *(double*)(&num6);
			}
			int pexp = 64;
			if ((num3 & 0xFFFFFFFF00000000uL) == 0L)
			{
				num3 <<= 32;
				pexp -= 32;
			}
			if ((num3 & 0xFFFF000000000000uL) == 0L)
			{
				num3 <<= 16;
				pexp -= 16;
			}
			if ((num3 & 0xFF00000000000000uL) == 0L)
			{
				num3 <<= 8;
				pexp -= 8;
			}
			if ((num3 & 0xF000000000000000uL) == 0L)
			{
				num3 <<= 4;
				pexp -= 4;
			}
			if ((num3 & 0xC000000000000000uL) == 0L)
			{
				num3 <<= 2;
				pexp -= 2;
			}
			if ((num3 & 0x8000000000000000uL) == 0L)
			{
				num3 <<= 1;
				pexp--;
			}
			int num7 = num5 & 0xF;
			if (num7 != 0)
			{
				int num8 = s_rgexp64Power10[num7 - 1];
				pexp += ((num4 < 0) ? (-num8 + 1) : num8);
				ulong b2 = s_rgval64Power10[num7 + ((num4 < 0) ? 15 : 0) - 1];
				num3 = Mul64Lossy(num3, b2, ref pexp);
			}
			num7 = num5 >> 4;
			if (num7 != 0)
			{
				int num9 = s_rgexp64Power10By16[num7 - 1];
				pexp += ((num4 < 0) ? (-num9 + 1) : num9);
				ulong b3 = s_rgval64Power10By16[num7 + ((num4 < 0) ? 21 : 0) - 1];
				num3 = Mul64Lossy(num3, b3, ref pexp);
			}
			if (((uint)(int)num3 & 0x400u) != 0)
			{
				ulong num10 = num3 + 1023 + (ulong)(((int)num3 >> 11) & 1);
				if (num10 < num3)
				{
					num10 = (num10 >> 1) | 0x8000000000000000uL;
					pexp++;
				}
				num3 = num10;
			}
			pexp += 1022;
			num3 = ((pexp <= 0) ? ((pexp == -52 && num3 >= 9223372036854775896uL) ? 1 : ((pexp > -52) ? (num3 >> -pexp + 11 + 1) : 0)) : ((pexp < 2047) ? ((ulong)((long)pexp << 52) + ((num3 >> 11) & 0xFFFFFFFFFFFFFL)) : 9218868437227405312uL));
			if (number.IsNegative)
			{
				num3 |= 0x8000000000000000uL;
			}
			return *(double*)(&num3);
		}
	}
	internal ref struct NumberBuffer
	{
		public int Scale;

		public bool IsNegative;

		public const int BufferSize = 51;

		private byte _b0;

		private byte _b1;

		private byte _b2;

		private byte _b3;

		private byte _b4;

		private byte _b5;

		private byte _b6;

		private byte _b7;

		private byte _b8;

		private byte _b9;

		private byte _b10;

		private byte _b11;

		private byte _b12;

		private byte _b13;

		private byte _b14;

		private byte _b15;

		private byte _b16;

		private byte _b17;

		private byte _b18;

		private byte _b19;

		private byte _b20;

		private byte _b21;

		private byte _b22;

		private byte _b23;

		private byte _b24;

		private byte _b25;

		private byte _b26;

		private byte _b27;

		private byte _b28;

		private byte _b29;

		private byte _b30;

		private byte _b31;

		private byte _b32;

		private byte _b33;

		private byte _b34;

		private byte _b35;

		private byte _b36;

		private byte _b37;

		private byte _b38;

		private byte _b39;

		private byte _b40;

		private byte _b41;

		private byte _b42;

		private byte _b43;

		private byte _b44;

		private byte _b45;

		private byte _b46;

		private byte _b47;

		private byte _b48;

		private byte _b49;

		private byte _b50;

		public unsafe Span<byte> Digits => new Span<byte>(System.Runtime.CompilerServices.Unsafe.AsPointer<byte>(ref _b0), 51);

		public unsafe byte* UnsafeDigits => (byte*)System.Runtime.CompilerServices.Unsafe.AsPointer<byte>(ref _b0);

		public int NumDigits => Digits.IndexOf<byte>(0);

		[Conditional("DEBUG")]
		public void CheckConsistency()
		{
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append('[');
			stringBuilder.Append('"');
			Span<byte> digits = Digits;
			for (int i = 0; i < 51; i++)
			{
				byte b = digits[i];
				if (b == 0)
				{
					break;
				}
				stringBuilder.Append((char)b);
			}
			stringBuilder.Append('"');
			stringBuilder.Append(", Scale = " + Scale);
			stringBuilder.Append(", IsNegative   = " + IsNegative);
			stringBuilder.Append(']');
			return stringBuilder.ToString();
		}
	}
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct Memory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		private const int RemoveFlagsBitMask = int.MaxValue;

		public static Memory<T> Empty => default(Memory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public Span<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				Span<T> result;
				if (_index < 0)
				{
					result = ((MemoryManager<T>)_object).GetSpan();
					return result.Slice(_index & 0x7FFFFFFF, _length);
				}
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new Span<T>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new Span<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(Span<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array)
		{
			if (array == null)
			{
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = array.Length - start;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int length)
		{
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int start, int length)
		{
			if (length < 0 || start < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = start | int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator Memory<T>(T[] array)
		{
			return new Memory<T>(array);
		}

		public static implicit operator Memory<T>(ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static implicit operator ReadOnlyMemory<T>(Memory<T> memory)
		{
			return System.Runtime.CompilerServices.Unsafe.As<Memory<T>, ReadOnlyMemory<T>>(ref memory);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.Memory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = length2 & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			return new Memory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = System.Runtime.CompilerServices.Unsafe.Add<T>(System.Runtime.CompilerServices.Unsafe.AsPointer<T>(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

		public T[] ToArray()
		{
			return Span.ToArray();
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> readOnlyMemory)
			{
				return readOnlyMemory.Equals(this);
			}
			if (obj is Memory<T> other)
			{
				return Equals(other);
			}
			return false;
		}

		public bool Equals(Memory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}
	}
	internal sealed class MemoryDebugView<T>
	{
		private readonly ReadOnlyMemory<T> _memory;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _memory.ToArray();

		public MemoryDebugView(Memory<T> memory)
		{
			_memory = memory;
		}

		public MemoryDebugView(ReadOnlyMemory<T> memory)
		{
			_memory = memory;
		}
	}
	public static class MemoryExtensions
	{
		internal static readonly IntPtr StringAdjustment = MeasureStringAdjustment();

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span)
		{
			return span.TrimStart().TrimEnd();
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span)
		{
			int i;
			for (i = 0; i < span.Length && char.IsWhiteSpace(span[i]); i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span)
		{
			int num = span.Length - 1;
			while (num >= 0 && char.IsWhiteSpace(span[num]))
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, char trimChar)
		{
			return span.TrimStart(trimChar).TrimEnd(trimChar);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, char trimChar)
		{
			int i;
			for (i = 0; i < span.Length && span[i] == trimChar; i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, char trimChar)
		{
			int num = span.Length - 1;
			while (num >= 0 && span[num] == trimChar)
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			return span.TrimStart(trimChars).TrimEnd(trimChars);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimStart();
			}
			int i;
			for (i = 0; i < span.Length; i++)
			{
				int num = 0;
				while (num < trimChars.Length)
				{
					if (span[i] != trimChars[num])
					{
						num++;
						continue;
					}
					goto IL_003c;
				}
				break;
				IL_003c:;
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimEnd();
			}
			int num;
			for (num = span.Length - 1; num >= 0; num--)
			{
				int num2 = 0;
				while (num2 < trimChars.Length)
				{
					if (span[num] != trimChars[num2])
					{
						num2++;
						continue;
					}
					goto IL_0044;
				}
				break;
				IL_0044:;
			}
			return span.Slice(0, num + 1);
		}

		public static bool IsWhiteSpace(this ReadOnlySpan<char> span)
		{
			for (int i = 0; i < span.Length; i++)
			{
				if (!char.IsWhiteSpace(span[i]))
				{
					return false;
				}
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		public static int SequenceCompareTo<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int SequenceCompareTo<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		public static void Reverse<T>(this Span<T> span)
		{
			ref T reference = ref MemoryMarshal.GetReference(span);
			int num = 0;
			int num2 = span.Length - 1;
			while (num < num2)
			{
				T val = System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num);
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num) = System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num2);
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num2) = val;
				num++;
				num2--;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array)
		{
			return new Span<T>(array);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array, int start, int length)
		{
			return new Span<T>(array, start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Span<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Span<T>(segment.Array, segment.Offset + start, length);
		}

		public static Memory<T> AsMemory<T>(this T[] array)
		{
			return new Memory<T>(array);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start)
		{
			return new Memory<T>(array, start);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start, int length)
		{
			return new Memory<T>(array, start, length);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Span<T> destination)
		{
			new ReadOnlySpan<T>(source).CopyTo(destination);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Memory<T> destination)
		{
			source.CopyTo(destination.Span);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other, out elementOffset);
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				return false;
			}
			IntPtr intPtr = System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr >= (uint)(span.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()))
				{
					return (uint)(int)intPtr > (uint)(-(other.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()));
				}
				return true;
			}
			if ((ulong)(long)intPtr >= (ulong)((long)span.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>()))
			{
				return (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>()));
			}
			return true;
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				elementOffset = 0;
				return false;
			}
			IntPtr intPtr = System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr < (uint)(span.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()) || (uint)(int)intPtr > (uint)(-(other.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>())))
				{
					if ((int)intPtr % System.Runtime.CompilerServices.Unsafe.SizeOf<T>() != 0)
					{
						System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
					}
					elementOffset = (int)intPtr / System.Runtime.CompilerServices.Unsafe.SizeOf<T>();
					return true;
				}
				elementOffset = 0;
				return false;
			}
			if ((ulong)(long)intPtr < (ulong)((long)span.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>()) || (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>())))
			{
				if ((long)intPtr % System.Runtime.CompilerServices.Unsafe.SizeOf<T>() != 0L)
				{
					System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
				}
				elementOffset = (int)((long)intPtr / System.Runtime.CompilerServices.Unsafe.SizeOf<T>());
				return true;
			}
			elementOffset = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this Span<T> span, IComparable<T> comparable)
		{
			return span.BinarySearch<T, IComparable<T>>(comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this Span<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return BinarySearch((ReadOnlySpan<T>)span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this Span<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			return ((ReadOnlySpan<T>)span).BinarySearch(value, comparer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this ReadOnlySpan<T> span, IComparable<T> comparable)
		{
			return MemoryExtensions.BinarySearch<T, IComparable<T>>(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return System.SpanHelpers.BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this ReadOnlySpan<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			if (comparer == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparer);
			}
			System.SpanHelpers.ComparerComparable<T, TComparer> comparable = new System.SpanHelpers.ComparerComparable<T, TComparer>(value, comparer);
			return BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool IsTypeComparableAsBytes<T>(out NUInt size)
		{
			if (typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte))
			{
				size = (NUInt)1;
				return true;
			}
			if (typeof(T) == typeof(char) || typeof(T) == typeof(short) || typeof(T) == typeof(ushort))
			{
				size = (NUInt)2;
				return true;
			}
			if (typeof(T) == typeof(int) || typeof(T) == typeof(uint))
			{
				size = (NUInt)4;
				return true;
			}
			if (typeof(T) == typeof(long) || typeof(T) == typeof(ulong))
			{
				size = (NUInt)8;
				return true;
			}
			size = default(NUInt);
			return false;
		}

		public static Span<T> AsSpan<T>(this T[] array, int start)
		{
			return Span<T>.Create(array, start);
		}

		public static bool Contains(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			return span.IndexOf(value, comparisonType) >= 0;
		}

		public static bool Equals(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.SequenceEqual(other);
			case StringComparison.OrdinalIgnoreCase:
				if (span.Length != other.Length)
				{
					return false;
				}
				return EqualsOrdinalIgnoreCase(span, other);
			default:
				return span.ToString().Equals(other.ToString(), comparisonType);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool EqualsOrdinalIgnoreCase(ReadOnlySpan<char> span, ReadOnlySpan<char> other)
		{
			if (other.Length == 0)
			{
				return true;
			}
			return CompareToOrdinalIgnoreCase(span, other) == 0;
		}

		public static int CompareTo(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			return comparisonType switch
			{
				StringComparison.Ordinal => span.SequenceCompareTo(other), 
				StringComparison.OrdinalIgnoreCase => CompareToOrdinalIgnoreCase(span, other), 
				_ => string.Compare(span.ToString(), other.ToString(), comparisonType), 
			};
		}

		private unsafe static int CompareToOrdinalIgnoreCase(ReadOnlySpan<char> strA, ReadOnlySpan<char> strB)
		{
			int num = Math.Min(strA.Length, strB.Length);
			int num2 = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(strA))
			{
				fixed (char* ptr3 = &MemoryMarshal.GetReference(strB))
				{
					char* ptr2 = ptr;
					char* ptr4 = ptr3;
					while (num != 0 && *ptr2 <= '\u007f' && *ptr4 <= '\u007f')
					{
						int num3 = *ptr2;
						int num4 = *ptr4;
						if (num3 == num4)
						{
							ptr2++;
							ptr4++;
							num--;
							continue;
						}
						if ((uint)(num3 - 97) <= 25u)
						{
							num3 -= 32;
						}
						if ((uint)(num4 - 97) <= 25u)
						{
							num4 -= 32;
						}
						if (num3 != num4)
						{
							return num3 - num4;
						}
						ptr2++;
						ptr4++;
						num--;
					}
					if (num == 0)
					{
						return strA.Length - strB.Length;
					}
					num2 -= num;
					return string.Compare(strA.Slice(num2).ToString(), strB.Slice(num2).ToString(), StringComparison.OrdinalIgnoreCase);
				}
			}
		}

		public static int IndexOf(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			if (comparisonType == StringComparison.Ordinal)
			{
				return span.IndexOf(value);
			}
			return span.ToString().IndexOf(value.ToString(), comparisonType);
		}

		public static int ToLower(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToLower(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToLowerInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToLower(destination, CultureInfo.InvariantCulture);
		}

		public static int ToUpper(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToUpper(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToUpperInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToUpper(destination, CultureInfo.InvariantCulture);
		}

		public static bool EndsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.EndsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(span.Length - value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.EndsWith(value2, comparisonType);
			}
			}
		}

		public static bool StartsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.StartsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(0, value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.StartsWith(value2, comparisonType);
			}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlySpan<char>);
			}
			return new ReadOnlySpan<char>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text), StringAdjustment, text.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text), StringAdjustment + start * 2, text.Length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text), StringAdjustment + start * 2, length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlyMemory<char>);
			}
			return new ReadOnlyMemory<char>(text, 0, text.Length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, text.Length - start);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, length);
		}

		private unsafe static IntPtr MeasureStringAdjustment()
		{
			string text = "a";
			fixed (char* ptr = text)
			{
				return System.Runtime.CompilerServices.Unsafe.ByteOffset<char>(ref System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text).Data, ref System.Runtime.CompilerServices.Unsafe.AsRef<char>((void*)ptr));
			}
		}
	}
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct ReadOnlyMemory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		internal const int RemoveFlagsBitMask = int.MaxValue;

		public static ReadOnlyMemory<T> Empty => default(ReadOnlyMemory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public ReadOnlySpan<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if (_index < 0)
				{
					return ((MemoryManager<T>)_object).GetSpan().Slice(_index & 0x7FFFFFFF, _length);
				}
				ReadOnlySpan<T> result;
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new ReadOnlySpan<T>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new ReadOnlySpan<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(ReadOnlySpan<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlyMemory<T>);
				return;
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(ReadOnlyMemory<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlyMemory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator ReadOnlyMemory<T>(T[] array)
		{
			return new ReadOnlyMemory<T>(array);
		}

		public static implicit operator ReadOnlyMemory<T>(ArraySegment<T> segment)
		{
			return new ReadOnlyMemory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.ReadOnlyMemory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = _length & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = System.Runtime.CompilerServices.Unsafe.Add<T>(System.Runtime.CompilerServices.Unsafe.AsPointer<T>(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

		public T[] ToArray()
		{
			return Span.ToArray();
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> other)
			{
				return Equals(other);
			}
			if (obj is Memory<T> memory)
			{
				return Equals(memory);
			}
			return false;
		}

		public bool Equals(ReadOnlyMemory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal object GetObjectStartLength(out int start, out int length)
		{
			start = _index;
			length = _length;
			return _object;
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct ReadOnlySpan<T>
	{
		public ref struct Enumerator
		{
			private readonly ReadOnlySpan<T> _span;

			private int _index;

			public ref readonly T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(ReadOnlySpan<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static ReadOnlySpan<T> Empty => default(ReadOnlySpan<T>);

		public unsafe ref readonly T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on ReadOnlySpan will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on ReadOnlySpan will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator ReadOnlySpan<T>(T[] array)
		{
			return new ReadOnlySpan<T>(array);
		}

		public static implicit operator ReadOnlySpan<T>(ArraySegment<T> segment)
		{
			return new ReadOnlySpan<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlySpan<T>);
				return;
			}
			_length = array.Length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(ReadOnlySpan<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe ReadOnlySpan(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlySpan(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref readonly T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
			}
			return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>((void*)null);
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination.Length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			if (left._length == right._length)
			{
				return System.Runtime.CompilerServices.Unsafe.AreSame<T>(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (_byteOffset == MemoryExtensions.StringAdjustment)
				{
					object obj = System.Runtime.CompilerServices.Unsafe.As<object>((object)_pinnable);
					if (obj is string text && _length == text.Length)
					{
						return text;
					}
				}
				fixed (char* value = &System.Runtime.CompilerServices.Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.ReadOnlySpan<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct Span<T>
	{
		public ref struct Enumerator
		{
			private readonly Span<T> _span;

			private int _index;

			public ref T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(Span<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static Span<T> Empty => default(Span<T>);

		public unsafe ref T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(Span<T> left, Span<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on Span will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on Span will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator Span<T>(T[] array)
		{
			return new Span<T>(array);
		}

		public static implicit operator Span<T>(ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array)
		{
			if (array == null)
			{
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_length = array.Length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static Span<T> Create(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(Span<T>);
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
			int length = array.Length - start;
			return new Span<T>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array), byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe Span(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Span(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
			}
			return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>((void*)null);
		}

		public unsafe void Clear()
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			UIntPtr byteLength = (UIntPtr)(ulong)((uint)length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>());
			if ((System.Runtime.CompilerServices.Unsafe.SizeOf<T>() & (sizeof(IntPtr) - 1)) != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					byte* ptr = (byte*)byteOffset.ToPointer();
					System.SpanHelpers.ClearLessThanPointerSized(ptr, byteLength);
				}
				else
				{
					System.SpanHelpers.ClearLessThanPointerSized(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset)), byteLength);
				}
			}
			else if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				UIntPtr pointerSizeLength = (UIntPtr)(ulong)(length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>() / sizeof(IntPtr));
				System.SpanHelpers.ClearPointerSizedWithReferences(ref System.Runtime.CompilerServices.Unsafe.As<T, IntPtr>(ref DangerousGetPinnableReference()), pointerSizeLength);
			}
			else
			{
				System.SpanHelpers.ClearPointerSizedWithoutReferences(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref DangerousGetPinnableReference()), byteLength);
			}
		}

		public unsafe void Fill(T value)
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<T>() == 1)
			{
				byte b = System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value);
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(byteOffset.ToPointer(), b, (uint)length);
				}
				else
				{
					System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset)), b, (uint)length);
				}
				return;
			}
			ref T reference = ref DangerousGetPinnableReference();
			int i;
			for (i = 0; i < (length & -8); i += 8)
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 1) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 2) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 3) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 4) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 5) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 6) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 7) = value;
			}
			if (i < (length & -4))
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 1) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 2) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 3) = value;
				i += 4;
			}
			for (; i < length; i++)
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i) = value;
			}
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination._length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(Span<T> left, Span<T> right)
		{
			if (left._length == right._length)
			{
				return System.Runtime.CompilerServices.Unsafe.AreSame<T>(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public static implicit operator ReadOnlySpan<T>(Span<T> span)
		{
			return new ReadOnlySpan<T>(span._pinnable, span._byteOffset, span._length);
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				fixed (char* value = &System.Runtime.CompilerServices.Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.Span<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new Span<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new Span<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
		}
	}
	internal sealed class SpanDebugView<T>
	{
		private readonly T[] _array;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _array;

		public SpanDebugView(Span<T> span)
		{
			_array = span.ToArray();
		}

		public SpanDebugView(ReadOnlySpan<T> span)
		{
			_array = span.ToArray();
		}
	}
	internal static class SpanHelpers
	{
		internal struct ComparerComparable<T, TComparer> : IComparable<T> where TComparer : IComparer<T>
		{
			private readonly T _value;

			private readonly TComparer _comparer;

			public ComparerComparable(T value, TComparer comparer)
			{
				_value = value;
				_comparer = comparer;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public int CompareTo(T other)
			{
				return _comparer.Compare(_value, other);
			}
		}

		[StructLayout(LayoutKind.Sequential, Size = 64)]
		private struct Reg64
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 32)]
		private struct Reg32
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 16)]
		private struct Reg16
		{
		}

		public static class PerTypeValues<T>
		{
			public static readonly bool IsReferenceOrContainsReferences = IsReferenceOrContainsReferencesCore(typeof(T));

			public static readonly T[] EmptyArray = new T[0];

			public static readonly IntPtr ArrayAdjustment = MeasureArrayAdjustment();

			private static IntPtr MeasureArrayAdjustment()
			{
				T[] array = new T[1];
				return System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array).Data, ref array[0]);
			}
		}

		private const ulong XorPowerOfTwoToHighByte = 283686952306184uL;

		private const ulong XorPowerOfTwoToHighChar = 4295098372uL;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			if (comparable == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparable);
			}
			return BinarySearch(ref MemoryMarshal.GetReference(span), span.Length, comparable);
		}

		public static int BinarySearch<T, TComparable>(ref T spanStart, int length, TComparable comparable) where TComparable : IComparable<T>
		{
			int num = 0;
			int num2 = length - 1;
			while (num <= num2)
			{
				int num3 = num2 + num >>> 1;
				int num4 = comparable.CompareTo(System.Runtime.CompilerServices.Unsafe.Add<T>(ref spanStart, num3));
				if (num4 == 0)
				{
					return num3;
				}
				if (num4 > 0)
				{
					num = num3 + 1;
				}
				else
				{
					num2 = num3 - 1;
				}
			}
			return ~num;
		}

		public static int IndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			byte value2 = value;
			ref byte second = ref System.Runtime.CompilerServices.Unsafe.Add<byte>(ref value, 1);
			int num = valueLength - 1;
			int num2 = 0;
			while (true)
			{
				int num3 = searchSpaceLength - num2 - num;
				if (num3 <= 0)
				{
					break;
				}
				int num4 = IndexOf(ref System.Runtime.CompilerServices.Unsafe.Add<byte>(ref searchSpace, num2), value2, num3);
				if (num4 == -1)
				{
					break;
				}
				num2 += num4;
				if (SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<byte>(ref searchSpace, num2 + 1), ref second, num))
				{
					return num2;
				}
				num2++;
			}
			return -1;
		}

		public static int IndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			int num = -1;
			for (int i = 0; i < valueLength; i++)
			{
				int num2 = IndexOf(ref searchSpace, System.Runtime.CompilerServices.Unsafe.Add<byte>(ref value, i), searchSpaceLength);
				if ((uint)num2 < (uint)num)
				{
					num = num2;
					searchSpaceLength = num2;
					if (num == 0)
					{
						break;
			

System.Numerics.Vectors.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FxResources.System.Numerics.Vectors;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Numerics.Vectors")]
[assembly: AssemblyDescription("System.Numerics.Vectors")]
[assembly: AssemblyDefaultAlias("System.Numerics.Vectors")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.26515.06")]
[assembly: AssemblyInformationalVersion("4.6.26515.06 @BuiltBy: dlab-DDVSOWINAGE059 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/30ab651fcb4354552bd4891619a0bdd81e0ebdbf")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.4.0")]
[assembly: TypeForwardedTo(typeof(Matrix3x2))]
[assembly: TypeForwardedTo(typeof(Matrix4x4))]
[assembly: TypeForwardedTo(typeof(Plane))]
[assembly: TypeForwardedTo(typeof(Quaternion))]
[assembly: TypeForwardedTo(typeof(Vector2))]
[assembly: TypeForwardedTo(typeof(Vector3))]
[assembly: TypeForwardedTo(typeof(Vector4))]
[module: UnverifiableCode]
namespace FxResources.System.Numerics.Vectors
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class MathF
	{
		public const float PI = 3.1415927f;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Abs(float x)
		{
			return Math.Abs(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Acos(float x)
		{
			return (float)Math.Acos(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Cos(float x)
		{
			return (float)Math.Cos(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float IEEERemainder(float x, float y)
		{
			return (float)Math.IEEERemainder(x, y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Pow(float x, float y)
		{
			return (float)Math.Pow(x, y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Sin(float x)
		{
			return (float)Math.Sin(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Sqrt(float x)
		{
			return (float)Math.Sqrt(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Tan(float x)
		{
			return (float)Math.Tan(x);
		}
	}
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static Type ResourceType { get; } = typeof(SR);


		internal static string Arg_ArgumentOutOfRangeException => GetResourceString("Arg_ArgumentOutOfRangeException", null);

		internal static string Arg_ElementsInSourceIsGreaterThanDestination => GetResourceString("Arg_ElementsInSourceIsGreaterThanDestination", null);

		internal static string Arg_NullArgumentNullRef => GetResourceString("Arg_NullArgumentNullRef", null);

		internal static string Arg_TypeNotSupported => GetResourceString("Arg_TypeNotSupported", null);

		internal static string Arg_InsufficientNumberOfElements => GetResourceString("Arg_InsufficientNumberOfElements", null);

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Field, Inherited = false)]
	internal sealed class IntrinsicAttribute : Attribute
	{
	}
}
namespace System.Numerics
{
	internal class ConstantHelper
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static byte GetByteWithAllBitsSet()
		{
			byte result = 0;
			result = byte.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static sbyte GetSByteWithAllBitsSet()
		{
			sbyte result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ushort GetUInt16WithAllBitsSet()
		{
			ushort result = 0;
			result = ushort.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static short GetInt16WithAllBitsSet()
		{
			short result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint GetUInt32WithAllBitsSet()
		{
			uint result = 0u;
			result = uint.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int GetInt32WithAllBitsSet()
		{
			int result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ulong GetUInt64WithAllBitsSet()
		{
			ulong result = 0uL;
			result = ulong.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static long GetInt64WithAllBitsSet()
		{
			long result = 0L;
			result = -1L;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static float GetSingleWithAllBitsSet()
		{
			float result = 0f;
			*(int*)(&result) = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static double GetDoubleWithAllBitsSet()
		{
			double result = 0.0;
			*(long*)(&result) = -1L;
			return result;
		}
	}
	[StructLayout(LayoutKind.Explicit)]
	internal struct Register
	{
		[FieldOffset(0)]
		internal byte byte_0;

		[FieldOffset(1)]
		internal byte byte_1;

		[FieldOffset(2)]
		internal byte byte_2;

		[FieldOffset(3)]
		internal byte byte_3;

		[FieldOffset(4)]
		internal byte byte_4;

		[FieldOffset(5)]
		internal byte byte_5;

		[FieldOffset(6)]
		internal byte byte_6;

		[FieldOffset(7)]
		internal byte byte_7;

		[FieldOffset(8)]
		internal byte byte_8;

		[FieldOffset(9)]
		internal byte byte_9;

		[FieldOffset(10)]
		internal byte byte_10;

		[FieldOffset(11)]
		internal byte byte_11;

		[FieldOffset(12)]
		internal byte byte_12;

		[FieldOffset(13)]
		internal byte byte_13;

		[FieldOffset(14)]
		internal byte byte_14;

		[FieldOffset(15)]
		internal byte byte_15;

		[FieldOffset(0)]
		internal sbyte sbyte_0;

		[FieldOffset(1)]
		internal sbyte sbyte_1;

		[FieldOffset(2)]
		internal sbyte sbyte_2;

		[FieldOffset(3)]
		internal sbyte sbyte_3;

		[FieldOffset(4)]
		internal sbyte sbyte_4;

		[FieldOffset(5)]
		internal sbyte sbyte_5;

		[FieldOffset(6)]
		internal sbyte sbyte_6;

		[FieldOffset(7)]
		internal sbyte sbyte_7;

		[FieldOffset(8)]
		internal sbyte sbyte_8;

		[FieldOffset(9)]
		internal sbyte sbyte_9;

		[FieldOffset(10)]
		internal sbyte sbyte_10;

		[FieldOffset(11)]
		internal sbyte sbyte_11;

		[FieldOffset(12)]
		internal sbyte sbyte_12;

		[FieldOffset(13)]
		internal sbyte sbyte_13;

		[FieldOffset(14)]
		internal sbyte sbyte_14;

		[FieldOffset(15)]
		internal sbyte sbyte_15;

		[FieldOffset(0)]
		internal ushort uint16_0;

		[FieldOffset(2)]
		internal ushort uint16_1;

		[FieldOffset(4)]
		internal ushort uint16_2;

		[FieldOffset(6)]
		internal ushort uint16_3;

		[FieldOffset(8)]
		internal ushort uint16_4;

		[FieldOffset(10)]
		internal ushort uint16_5;

		[FieldOffset(12)]
		internal ushort uint16_6;

		[FieldOffset(14)]
		internal ushort uint16_7;

		[FieldOffset(0)]
		internal short int16_0;

		[FieldOffset(2)]
		internal short int16_1;

		[FieldOffset(4)]
		internal short int16_2;

		[FieldOffset(6)]
		internal short int16_3;

		[FieldOffset(8)]
		internal short int16_4;

		[FieldOffset(10)]
		internal short int16_5;

		[FieldOffset(12)]
		internal short int16_6;

		[FieldOffset(14)]
		internal short int16_7;

		[FieldOffset(0)]
		internal uint uint32_0;

		[FieldOffset(4)]
		internal uint uint32_1;

		[FieldOffset(8)]
		internal uint uint32_2;

		[FieldOffset(12)]
		internal uint uint32_3;

		[FieldOffset(0)]
		internal int int32_0;

		[FieldOffset(4)]
		internal int int32_1;

		[FieldOffset(8)]
		internal int int32_2;

		[FieldOffset(12)]
		internal int int32_3;

		[FieldOffset(0)]
		internal ulong uint64_0;

		[FieldOffset(8)]
		internal ulong uint64_1;

		[FieldOffset(0)]
		internal long int64_0;

		[FieldOffset(8)]
		internal long int64_1;

		[FieldOffset(0)]
		internal float single_0;

		[FieldOffset(4)]
		internal float single_1;

		[FieldOffset(8)]
		internal float single_2;

		[FieldOffset(12)]
		internal float single_3;

		[FieldOffset(0)]
		internal double double_0;

		[FieldOffset(8)]
		internal double double_1;
	}
	[System.Runtime.CompilerServices.Intrinsic]
	public struct Vector<T> : IEquatable<Vector<T>>, IFormattable where T : struct
	{
		private struct VectorSizeHelper
		{
			internal Vector<T> _placeholder;

			internal byte _byte;
		}

		private System.Numerics.Register register;

		private static readonly int s_count = InitializeCount();

		private static readonly Vector<T> s_zero = default(Vector<T>);

		private static readonly Vector<T> s_one = new Vector<T>(GetOneValue());

		private static readonly Vector<T> s_allOnes = new Vector<T>(GetAllBitsSetValue());

		public static int Count
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_count;
			}
		}

		public static Vector<T> Zero
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_zero;
			}
		}

		public static Vector<T> One
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_one;
			}
		}

		internal static Vector<T> AllOnes => s_allOnes;

		public unsafe T this[int index]
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				if (index >= Count || index < 0)
				{
					throw new IndexOutOfRangeException(System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, index));
				}
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						return (T)(object)ptr[index];
					}
				}
				if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						return (T)(object)ptr2[index];
					}
				}
				if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						return (T)(object)ptr3[index];
					}
				}
				if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						return (T)(object)ptr4[index];
					}
				}
				if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						return (T)(object)ptr5[index];
					}
				}
				if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						return (T)(object)ptr6[index];
					}
				}
				if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						return (T)(object)ptr7[index];
					}
				}
				if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						return (T)(object)ptr8[index];
					}
				}
				if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						return (T)(object)ptr9[index];
					}
				}
				if (typeof(T) == typeof(double))
				{
					fixed (double* ptr10 = &register.double_0)
					{
						return (T)(object)ptr10[index];
					}
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
		}

		private unsafe static int InitializeCount()
		{
			VectorSizeHelper vectorSizeHelper = default(VectorSizeHelper);
			byte* ptr = &vectorSizeHelper._placeholder.register.byte_0;
			byte* ptr2 = &vectorSizeHelper._byte;
			int num = (int)(ptr2 - ptr);
			int num2 = -1;
			if (typeof(T) == typeof(byte))
			{
				num2 = 1;
			}
			else if (typeof(T) == typeof(sbyte))
			{
				num2 = 1;
			}
			else if (typeof(T) == typeof(ushort))
			{
				num2 = 2;
			}
			else if (typeof(T) == typeof(short))
			{
				num2 = 2;
			}
			else if (typeof(T) == typeof(uint))
			{
				num2 = 4;
			}
			else if (typeof(T) == typeof(int))
			{
				num2 = 4;
			}
			else if (typeof(T) == typeof(ulong))
			{
				num2 = 8;
			}
			else if (typeof(T) == typeof(long))
			{
				num2 = 8;
			}
			else if (typeof(T) == typeof(float))
			{
				num2 = 4;
			}
			else
			{
				if (!(typeof(T) == typeof(double)))
				{
					throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
				}
				num2 = 8;
			}
			return num / num2;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public unsafe Vector(T value)
		{
			this = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[i] = (byte)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[j] = (sbyte)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[k] = (ushort)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[l] = (short)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[m] = (uint)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[n] = (int)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[num] = (ulong)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[num2] = (long)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[num3] = (float)(object)value;
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = &register.double_0)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[num4] = (double)(object)value;
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				register.byte_0 = (byte)(object)value;
				register.byte_1 = (byte)(object)value;
				register.byte_2 = (byte)(object)value;
				register.byte_3 = (byte)(object)value;
				register.byte_4 = (byte)(object)value;
				register.byte_5 = (byte)(object)value;
				register.byte_6 = (byte)(object)value;
				register.byte_7 = (byte)(object)value;
				register.byte_8 = (byte)(object)value;
				register.byte_9 = (byte)(object)value;
				register.byte_10 = (byte)(object)value;
				register.byte_11 = (byte)(object)value;
				register.byte_12 = (byte)(object)value;
				register.byte_13 = (byte)(object)value;
				register.byte_14 = (byte)(object)value;
				register.byte_15 = (byte)(object)value;
			}
			else if (typeof(T) == typeof(sbyte))
			{
				register.sbyte_0 = (sbyte)(object)value;
				register.sbyte_1 = (sbyte)(object)value;
				register.sbyte_2 = (sbyte)(object)value;
				register.sbyte_3 = (sbyte)(object)value;
				register.sbyte_4 = (sbyte)(object)value;
				register.sbyte_5 = (sbyte)(object)value;
				register.sbyte_6 = (sbyte)(object)value;
				register.sbyte_7 = (sbyte)(object)value;
				register.sbyte_8 = (sbyte)(object)value;
				register.sbyte_9 = (sbyte)(object)value;
				register.sbyte_10 = (sbyte)(object)value;
				register.sbyte_11 = (sbyte)(object)value;
				register.sbyte_12 = (sbyte)(object)value;
				register.sbyte_13 = (sbyte)(object)value;
				register.sbyte_14 = (sbyte)(object)value;
				register.sbyte_15 = (sbyte)(object)value;
			}
			else if (typeof(T) == typeof(ushort))
			{
				register.uint16_0 = (ushort)(object)value;
				register.uint16_1 = (ushort)(object)value;
				register.uint16_2 = (ushort)(object)value;
				register.uint16_3 = (ushort)(object)value;
				register.uint16_4 = (ushort)(object)value;
				register.uint16_5 = (ushort)(object)value;
				register.uint16_6 = (ushort)(object)value;
				register.uint16_7 = (ushort)(object)value;
			}
			else if (typeof(T) == typeof(short))
			{
				register.int16_0 = (short)(object)value;
				register.int16_1 = (short)(object)value;
				register.int16_2 = (short)(object)value;
				register.int16_3 = (short)(object)value;
				register.int16_4 = (short)(object)value;
				register.int16_5 = (short)(object)value;
				register.int16_6 = (short)(object)value;
				register.int16_7 = (short)(object)value;
			}
			else if (typeof(T) == typeof(uint))
			{
				register.uint32_0 = (uint)(object)value;
				register.uint32_1 = (uint)(object)value;
				register.uint32_2 = (uint)(object)value;
				register.uint32_3 = (uint)(object)value;
			}
			else if (typeof(T) == typeof(int))
			{
				register.int32_0 = (int)(object)value;
				register.int32_1 = (int)(object)value;
				register.int32_2 = (int)(object)value;
				register.int32_3 = (int)(object)value;
			}
			else if (typeof(T) == typeof(ulong))
			{
				register.uint64_0 = (ulong)(object)value;
				register.uint64_1 = (ulong)(object)value;
			}
			else if (typeof(T) == typeof(long))
			{
				register.int64_0 = (long)(object)value;
				register.int64_1 = (long)(object)value;
			}
			else if (typeof(T) == typeof(float))
			{
				register.single_0 = (float)(object)value;
				register.single_1 = (float)(object)value;
				register.single_2 = (float)(object)value;
				register.single_3 = (float)(object)value;
			}
			else if (typeof(T) == typeof(double))
			{
				register.double_0 = (double)(object)value;
				register.double_1 = (double)(object)value;
			}
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public Vector(T[] values)
			: this(values, 0)
		{
		}

		public unsafe Vector(T[] values, int index)
		{
			this = default(Vector<T>);
			if (values == null)
			{
				throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef);
			}
			if (index < 0 || values.Length - index < Count)
			{
				throw new IndexOutOfRangeException(System.SR.Format(System.SR.Arg_InsufficientNumberOfElements, Count, "values"));
			}
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[i] = (byte)(object)values[i + index];
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[j] = (sbyte)(object)values[j + index];
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[k] = (ushort)(object)values[k + index];
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[l] = (short)(object)values[l + index];
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[m] = (uint)(object)values[m + index];
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[n] = (int)(object)values[n + index];
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[num] = (ulong)(object)values[num + index];
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[num2] = (long)(object)values[num2 + index];
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[num3] = (float)(object)values[num3 + index];
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = &register.double_0)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[num4] = (double)(object)values[num4 + index];
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				fixed (byte* ptr11 = &register.byte_0)
				{
					*ptr11 = (byte)(object)values[index];
					ptr11[1] = (byte)(object)values[1 + index];
					ptr11[2] = (byte)(object)values[2 + index];
					ptr11[3] = (byte)(object)values[3 + index];
					ptr11[4] = (byte)(object)values[4 + index];
					ptr11[5] = (byte)(object)values[5 + index];
					ptr11[6] = (byte)(object)values[6 + index];
					ptr11[7] = (byte)(object)values[7 + index];
					ptr11[8] = (byte)(object)values[8 + index];
					ptr11[9] = (byte)(object)values[9 + index];
					ptr11[10] = (byte)(object)values[10 + index];
					ptr11[11] = (byte)(object)values[11 + index];
					ptr11[12] = (byte)(object)values[12 + index];
					ptr11[13] = (byte)(object)values[13 + index];
					ptr11[14] = (byte)(object)values[14 + index];
					ptr11[15] = (byte)(object)values[15 + index];
				}
			}
			else if (typeof(T) == typeof(sbyte))
			{
				fixed (sbyte* ptr12 = &register.sbyte_0)
				{
					*ptr12 = (sbyte)(object)values[index];
					ptr12[1] = (sbyte)(object)values[1 + index];
					ptr12[2] = (sbyte)(object)values[2 + index];
					ptr12[3] = (sbyte)(object)values[3 + index];
					ptr12[4] = (sbyte)(object)values[4 + index];
					ptr12[5] = (sbyte)(object)values[5 + index];
					ptr12[6] = (sbyte)(object)values[6 + index];
					ptr12[7] = (sbyte)(object)values[7 + index];
					ptr12[8] = (sbyte)(object)values[8 + index];
					ptr12[9] = (sbyte)(object)values[9 + index];
					ptr12[10] = (sbyte)(object)values[10 + index];
					ptr12[11] = (sbyte)(object)values[11 + index];
					ptr12[12] = (sbyte)(object)values[12 + index];
					ptr12[13] = (sbyte)(object)values[13 + index];
					ptr12[14] = (sbyte)(object)values[14 + index];
					ptr12[15] = (sbyte)(object)values[15 + index];
				}
			}
			else if (typeof(T) == typeof(ushort))
			{
				fixed (ushort* ptr13 = &register.uint16_0)
				{
					*ptr13 = (ushort)(object)values[index];
					ptr13[1] = (ushort)(object)values[1 + index];
					ptr13[2] = (ushort)(object)values[2 + index];
					ptr13[3] = (ushort)(object)values[3 + index];
					ptr13[4] = (ushort)(object)values[4 + index];
					ptr13[5] = (ushort)(object)values[5 + index];
					ptr13[6] = (ushort)(object)values[6 + index];
					ptr13[7] = (ushort)(object)values[7 + index];
				}
			}
			else if (typeof(T) == typeof(short))
			{
				fixed (short* ptr14 = &register.int16_0)
				{
					*ptr14 = (short)(object)values[index];
					ptr14[1] = (short)(object)values[1 + index];
					ptr14[2] = (short)(object)values[2 + index];
					ptr14[3] = (short)(object)values[3 + index];
					ptr14[4] = (short)(object)values[4 + index];
					ptr14[5] = (short)(object)values[5 + index];
					ptr14[6] = (short)(object)values[6 + index];
					ptr14[7] = (short)(object)values[7 + index];
				}
			}
			else if (typeof(T) == typeof(uint))
			{
				fixed (uint* ptr15 = &register.uint32_0)
				{
					*ptr15 = (uint)(object)values[index];
					ptr15[1] = (uint)(object)values[1 + index];
					ptr15[2] = (uint)(object)values[2 + index];
					ptr15[3] = (uint)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(int))
			{
				fixed (int* ptr16 = &register.int32_0)
				{
					*ptr16 = (int)(object)values[index];
					ptr16[1] = (int)(object)values[1 + index];
					ptr16[2] = (int)(object)values[2 + index];
					ptr16[3] = (int)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(ulong))
			{
				fixed (ulong* ptr17 = &register.uint64_0)
				{
					*ptr17 = (ulong)(object)values[index];
					ptr17[1] = (ulong)(object)values[1 + index];
				}
			}
			else if (typeof(T) == typeof(long))
			{
				fixed (long* ptr18 = &register.int64_0)
				{
					*ptr18 = (long)(object)values[index];
					ptr18[1] = (long)(object)values[1 + index];
				}
			}
			else if (typeof(T) == typeof(float))
			{
				fixed (float* ptr19 = &register.single_0)
				{
					*ptr19 = (float)(object)values[index];
					ptr19[1] = (float)(object)values[1 + index];
					ptr19[2] = (float)(object)values[2 + index];
					ptr19[3] = (float)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(double))
			{
				fixed (double* ptr20 = &register.double_0)
				{
					*ptr20 = (double)(object)values[index];
					ptr20[1] = (double)(object)values[1 + index];
				}
			}
		}

		internal unsafe Vector(void* dataPointer)
			: this(dataPointer, 0)
		{
		}

		internal unsafe Vector(void* dataPointer, int offset)
		{
			this = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				byte* ptr = (byte*)dataPointer;
				ptr += offset;
				fixed (byte* ptr2 = &register.byte_0)
				{
					for (int i = 0; i < Count; i++)
					{
						ptr2[i] = ptr[i];
					}
				}
				return;
			}
			if (typeof(T) == typeof(sbyte))
			{
				sbyte* ptr3 = (sbyte*)dataPointer;
				ptr3 += offset;
				fixed (sbyte* ptr4 = &register.sbyte_0)
				{
					for (int j = 0; j < Count; j++)
					{
						ptr4[j] = ptr3[j];
					}
				}
				return;
			}
			if (typeof(T) == typeof(ushort))
			{
				ushort* ptr5 = (ushort*)dataPointer;
				ptr5 += offset;
				fixed (ushort* ptr6 = &register.uint16_0)
				{
					for (int k = 0; k < Count; k++)
					{
						ptr6[k] = ptr5[k];
					}
				}
				return;
			}
			if (typeof(T) == typeof(short))
			{
				short* ptr7 = (short*)dataPointer;
				ptr7 += offset;
				fixed (short* ptr8 = &register.int16_0)
				{
					for (int l = 0; l < Count; l++)
					{
						ptr8[l] = ptr7[l];
					}
				}
				return;
			}
			if (typeof(T) == typeof(uint))
			{
				uint* ptr9 = (uint*)dataPointer;
				ptr9 += offset;
				fixed (uint* ptr10 = &register.uint32_0)
				{
					for (int m = 0; m < Count; m++)
					{
						ptr10[m] = ptr9[m];
					}
				}
				return;
			}
			if (typeof(T) == typeof(int))
			{
				int* ptr11 = (int*)dataPointer;
				ptr11 += offset;
				fixed (int* ptr12 = &register.int32_0)
				{
					for (int n = 0; n < Count; n++)
					{
						ptr12[n] = ptr11[n];
					}
				}
				return;
			}
			if (typeof(T) == typeof(ulong))
			{
				ulong* ptr13 = (ulong*)dataPointer;
				ptr13 += offset;
				fixed (ulong* ptr14 = &register.uint64_0)
				{
					for (int num = 0; num < Count; num++)
					{
						ptr14[num] = ptr13[num];
					}
				}
				return;
			}
			if (typeof(T) == typeof(long))
			{
				long* ptr15 = (long*)dataPointer;
				ptr15 += offset;
				fixed (long* ptr16 = &register.int64_0)
				{
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr16[num2] = ptr15[num2];
					}
				}
				return;
			}
			if (typeof(T) == typeof(float))
			{
				float* ptr17 = (float*)dataPointer;
				ptr17 += offset;
				fixed (float* ptr18 = &register.single_0)
				{
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr18[num3] = ptr17[num3];
					}
				}
				return;
			}
			if (typeof(T) == typeof(double))
			{
				double* ptr19 = (double*)dataPointer;
				ptr19 += offset;
				fixed (double* ptr20 = &register.double_0)
				{
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr20[num4] = ptr19[num4];
					}
				}
				return;
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		private Vector(ref System.Numerics.Register existingRegister)
		{
			register = existingRegister;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public void CopyTo(T[] destination)
		{
			CopyTo(destination, 0);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public unsafe void CopyTo(T[] destination, int startIndex)
		{
			if (destination == null)
			{
				throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef);
			}
			if (startIndex < 0 || startIndex >= destination.Length)
			{
				throw new ArgumentOutOfRangeException("startIndex", System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, startIndex));
			}
			if (destination.Length - startIndex < Count)
			{
				throw new ArgumentException(System.SR.Format(System.SR.Arg_ElementsInSourceIsGreaterThanDestination, startIndex));
			}
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = (byte[])(object)destination)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[startIndex + i] = (byte)(object)this[i];
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = (sbyte[])(object)destination)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[startIndex + j] = (sbyte)(object)this[j];
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = (ushort[])(object)destination)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[startIndex + k] = (ushort)(object)this[k];
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = (short[])(object)destination)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[startIndex + l] = (short)(object)this[l];
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = (uint[])(object)destination)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[startIndex + m] = (uint)(object)this[m];
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = (int[])(object)destination)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[startIndex + n] = (int)(object)this[n];
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = (ulong[])(object)destination)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[startIndex + num] = (ulong)(object)this[num];
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = (long[])(object)destination)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[startIndex + num2] = (long)(object)this[num2];
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = (float[])(object)destination)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[startIndex + num3] = (float)(object)this[num3];
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = (double[])(object)destination)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[startIndex + num4] = (double)(object)this[num4];
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				fixed (byte* ptr11 = (byte[])(object)destination)
				{
					ptr11[startIndex] = register.byte_0;
					ptr11[startIndex + 1] = register.byte_1;
					ptr11[startIndex + 2] = register.byte_2;
					ptr11[startIndex + 3] = register.byte_3;
					ptr11[startIndex + 4] = register.byte_4;
					ptr11[startIndex + 5] = register.byte_5;
					ptr11[startIndex + 6] = register.byte_6;
					ptr11[startIndex + 7] = register.byte_7;
					ptr11[startIndex + 8] = register.byte_8;
					ptr11[startIndex + 9] = register.byte_9;
					ptr11[startIndex + 10] = register.byte_10;
					ptr11[startIndex + 11] = register.byte_11;
					ptr11[startIndex + 12] = register.byte_12;
					ptr11[startIndex + 13] = register.byte_13;
					ptr11[startIndex + 14] = register.byte_14;
					ptr11[startIndex + 15] = register.byte_15;
				}
			}
			else if (typeof(T) == typeof(sbyte))
			{
				fixed (sbyte* ptr12 = (sbyte[])(object)destination)
				{
					ptr12[startIndex] = register.sbyte_0;
					ptr12[startIndex + 1] = register.sbyte_1;
					ptr12[startIndex + 2] = register.sbyte_2;
					ptr12[startIndex + 3] = register.sbyte_3;
					ptr12[startIndex + 4] = register.sbyte_4;
					ptr12[startIndex + 5] = register.sbyte_5;
					ptr12[startIndex + 6] = register.sbyte_6;
					ptr12[startIndex + 7] = register.sbyte_7;
					ptr12[startIndex + 8] = register.sbyte_8;
					ptr12[startIndex + 9] = register.sbyte_9;
					ptr12[startIndex + 10] = register.sbyte_10;
					ptr12[startIndex + 11] = register.sbyte_11;
					ptr12[startIndex + 12] = register.sbyte_12;
					ptr12[startIndex + 13] = register.sbyte_13;
					ptr12[startIndex + 14] = register.sbyte_14;
					ptr12[startIndex + 15] = register.sbyte_15;
				}
			}
			else if (typeof(T) == typeof(ushort))
			{
				fixed (ushort* ptr13 = (ushort[])(object)destination)
				{
					ptr13[startIndex] = register.uint16_0;
					ptr13[startIndex + 1] = register.uint16_1;
					ptr13[startIndex + 2] = register.uint16_2;
					ptr13[startIndex + 3] = register.uint16_3;
					ptr13[startIndex + 4] = register.uint16_4;
					ptr13[startIndex + 5] = register.uint16_5;
					ptr13[startIndex + 6] = register.uint16_6;
					ptr13[startIndex + 7] = register.uint16_7;
				}
			}
			else if (typeof(T) == typeof(short))
			{
				fixed (short* ptr14 = (short[])(object)destination)
				{
					ptr14[startIndex] = register.int16_0;
					ptr14[startIndex + 1] = register.int16_1;
					ptr14[startIndex + 2] = register.int16_2;
					ptr14[startIndex + 3] = register.int16_3;
					ptr14[startIndex + 4] = register.int16_4;
					ptr14[startIndex + 5] = register.int16_5;
					ptr14[startIndex + 6] = register.int16_6;
					ptr14[startIndex + 7] = register.int16_7;
				}
			}
			else if (typeof(T) == typeof(uint))
			{
				fixed (uint* ptr15 = (uint[])(object)destination)
				{
					ptr15[startIndex] = register.uint32_0;
					ptr15[startIndex + 1] = register.uint32_1;
					ptr15[startIndex + 2] = register.uint32_2;
					ptr15[startIndex + 3] = register.uint32_3;
				}
			}
			else if (typeof(T) == typeof(int))
			{
				fixed (int* ptr16 = (int[])(object)destination)
				{
					ptr16[startIndex] = register.int32_0;
					ptr16[startIndex + 1] = register.int32_1;
					ptr16[startIndex + 2] = register.int32_2;
					ptr16[startIndex + 3] = register.int32_3;
				}
			}
			else if (typeof(T) == typeof(ulong))
			{
				fixed (ulong* ptr17 = (ulong[])(object)destination)
				{
					ptr17[startIndex] = register.uint64_0;
					ptr17[startIndex + 1] = register.uint64_1;
				}
			}
			else if (typeof(T) == typeof(long))
			{
				fixed (long* ptr18 = (long[])(object)destination)
				{
					ptr18[startIndex] = register.int64_0;
					ptr18[startIndex + 1] = register.int64_1;
				}
			}
			else if (typeof(T) == typeof(float))
			{
				fixed (float* ptr19 = (float[])(object)destination)
				{
					ptr19[startIndex] = register.single_0;
					ptr19[startIndex + 1] = register.single_1;
					ptr19[startIndex + 2] = register.single_2;
					ptr19[startIndex + 3] = register.single_3;
				}
			}
			else if (typeof(T) == typeof(double))
			{
				fixed (double* ptr20 = (double[])(object)destination)
				{
					ptr20[startIndex] = register.double_0;
					ptr20[startIndex + 1] = register.double_1;
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public override bool Equals(object obj)
		{
			if (!(obj is Vector<T>))
			{
				return false;
			}
			return Equals((Vector<T>)obj);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public bool Equals(Vector<T> other)
		{
			if (Vector.IsHardwareAccelerated)
			{
				for (int i = 0; i < Count; i++)
				{
					if (!ScalarEquals(this[i], other[i]))
					{
						return false;
					}
				}
				return true;
			}
			if (typeof(T) == typeof(byte))
			{
				if (register.byte_0 == other.register.byte_0 && register.byte_1 == other.register.byte_1 && register.byte_2 == other.register.byte_2 && register.byte_3 == other.register.byte_3 && register.byte_4 == other.register.byte_4 && register.byte_5 == other.register.byte_5 && register.byte_6 == other.register.byte_6 && register.byte_7 == other.register.byte_7 && register.byte_8 == other.register.byte_8 && register.byte_9 == other.register.byte_9 && register.byte_10 == other.register.byte_10 && register.byte_11 == other.register.byte_11 && register.byte_12 == other.register.byte_12 && register.byte_13 == other.register.byte_13 && register.byte_14 == other.register.byte_14)
				{
					return register.byte_15 == other.register.byte_15;
				}
				return false;
			}
			if (typeof(T) == typeof(sbyte))
			{
				if (register.sbyte_0 == other.register.sbyte_0 && register.sbyte_1 == other.register.sbyte_1 && register.sbyte_2 == other.register.sbyte_2 && register.sbyte_3 == other.register.sbyte_3 && register.sbyte_4 == other.register.sbyte_4 && register.sbyte_5 == other.register.sbyte_5 && register.sbyte_6 == other.register.sbyte_6 && register.sbyte_7 == other.register.sbyte_7 && register.sbyte_8 == other.register.sbyte_8 && register.sbyte_9 == other.register.sbyte_9 && register.sbyte_10 == other.register.sbyte_10 && register.sbyte_11 == other.register.sbyte_11 && register.sbyte_12 == other.register.sbyte_12 && register.sbyte_13 == other.register.sbyte_13 && register.sbyte_14 == other.register.sbyte_14)
				{
					return register.sbyte_15 == other.register.sbyte_15;
				}
				return false;
			}
			if (typeof(T) == typeof(ushort))
			{
				if (register.uint16_0 == other.register.uint16_0 && register.uint16_1 == other.register.uint16_1 && register.uint16_2 == other.register.uint16_2 && register.uint16_3 == other.register.uint16_3 && register.uint16_4 == other.register.uint16_4 && register.uint16_5 == other.register.uint16_5 && register.uint16_6 == other.register.uint16_6)
				{
					return register.uint16_7 == other.register.uint16_7;
				}
				return false;
			}
			if (typeof(T) == typeof(short))
			{
				if (register.int16_0 == other.register.int16_0 && register.int16_1 == other.register.int16_1 && register.int16_2 == other.register.int16_2 && register.int16_3 == other.register.int16_3 && register.int16_4 == other.register.int16_4 && register.int16_5 == other.register.int16_5 && register.int16_6 == other.register.int16_6)
				{
					return register.int16_7 == other.register.int16_7;
				}
				return false;
			}
			if (typeof(T) == typeof(uint))
			{
				if (register.uint32_0 == other.register.uint32_0 && register.uint32_1 == other.register.uint32_1 && register.uint32_2 == other.register.uint32_2)
				{
					return register.uint32_3 == other.register.uint32_3;
				}
				return false;
			}
			if (typeof(T) == typeof(int))
			{
				if (register.int32_0 == other.register.int32_0 && register.int32_1 == other.register.int32_1 && register.int32_2 == other.register.int32_2)
				{
					return register.int32_3 == other.register.int32_3;
				}
				return false;
			}
			if (typeof(T) == typeof(ulong))
			{
				if (register.uint64_0 == other.register.uint64_0)
				{
					return register.uint64_1 == other.register.uint64_1;
				}
				return false;
			}
			if (typeof(T) == typeof(long))
			{
				if (register.int64_0 == other.register.int64_0)
				{
					return register.int64_1 == other.register.int64_1;
				}
				return false;
			}
			if (typeof(T) == typeof(float))
			{
				if (register.single_0 == other.register.single_0 && register.single_1 == other.register.single_1 && register.single_2 == other.register.single_2)
				{
					return register.single_3 == other.register.single_3;
				}
				return false;
			}
			if (typeof(T) == typeof(double))
			{
				if (register.double_0 == other.register.double_0)
				{
					return register.double_1 == other.register.double_1;
				}
				return false;
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		public override int GetHashCode()
		{
			int num = 0;
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					for (int i = 0; i < Count; i++)
					{
						num = HashHelpers.Combine(num, ((byte)(object)this[i]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(sbyte))
				{
					for (int j = 0; j < Count; j++)
					{
						num = HashHelpers.Combine(num, ((sbyte)(object)this[j]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(ushort))
				{
					for (int k = 0; k < Count; k++)
					{
						num = HashHelpers.Combine(num, ((ushort)(object)this[k]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(short))
				{
					for (int l = 0; l < Count; l++)
					{
						num = HashHelpers.Combine(num, ((short)(object)this[l]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(uint))
				{
					for (int m = 0; m < Count; m++)
					{
						num = HashHelpers.Combine(num, ((uint)(object)this[m]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(int))
				{
					for (int n = 0; n < Count; n++)
					{
						num = HashHelpers.Combine(num, ((int)(object)this[n]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(ulong))
				{
					for (int num2 = 0; num2 < Count; num2++)
					{
						num = HashHelpers.Combine(num, ((ulong)(object)this[num2]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(long))
				{
					for (int num3 = 0; num3 < Count; num3++)
					{
						num = HashHelpers.Combine(num, ((long)(object)this[num3]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(float))
				{
					for (int num4 = 0; num4 < Count; num4++)
					{
						num = HashHelpers.Combine(num, ((float)(object)this[num4]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(double))
				{
					for (int num5 = 0; num5 < Count; num5++)
					{
						num = HashHelpers.Combine(num, ((double)(object)this[num5]).GetHashCode());
					}
					return num;
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			if (typeof(T) == typeof(byte))
			{
				num = HashHelpers.Combine(num, register.byte_0.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_1.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_2.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_3.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_4.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_5.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_6.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_7.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_8.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_9.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_10.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_11.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_12.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_13.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_14.GetHashCode());
				return HashHelpers.Combine(num, register.byte_15.GetHashCode());
			}
			if (typeof(T) == typeof(sbyte))
			{
				num = HashHelpers.Combine(num, register.sbyte_0.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_1.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_2.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_3.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_4.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_5.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_6.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_7.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_8.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_9.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_10.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_11.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_12.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_13.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_14.GetHashCode());
				return HashHelpers.Combine(num, register.sbyte_15.GetHashCode());
			}
			if (typeof(T) == typeof(ushort))
			{
				num = HashHelpers.Combine(num, register.uint16_0.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_1.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_2.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_3.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_4.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_5.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_6.GetHashCode());
				return HashHelpers.Combine(num, register.uint16_7.GetHashCode());
			}
			if (typeof(T) == typeof(short))
			{
				num = HashHelpers.Combine(num, register.int16_0.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_1.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_2.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_3.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_4.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_5.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_6.GetHashCode());
				return HashHelpers.Combine(num, register.int16_7.GetHashCode());
			}
			if (typeof(T) == typeof(uint))
			{
				num = HashHelpers.Combine(num, register.uint32_0.GetHashCode());
				num = HashHelpers.Combine(num, register.uint32_1.GetHashCode());
				num = HashHelpers.Combine(num, register.uint32_2.GetHashCode());
				return HashHelpers.Combine(num, register.uint32_3.GetHashCode());
			}
			if (typeof(T) == typeof(int))
			{
				num = HashHelpers.Combine(num, register.int32_0.GetHashCode());
				num = HashHelpers.Combine(num, register.int32_1.GetHashCode());
				num = HashHelpers.Combine(num, register.int32_2.GetHashCode());
				return HashHelpers.Combine(num, register.int32_3.GetHashCode());
			}
			if (typeof(T) == typeof(ulong))
			{
				num = HashHelpers.Combine(num, register.uint64_0.GetHashCode());
				return HashHelpers.Combine(num, register.uint64_1.GetHashCode());
			}
			if (typeof(T) == typeof(long))
			{
				num = HashHelpers.Combine(num, register.int64_0.GetHashCode());
				return HashHelpers.Combine(num, register.int64_1.GetHashCode());
			}
			if (typeof(T) == typeof(float))
			{
				num = HashHelpers.Combine(num, register.single_0.GetHashCode());
				num = HashHelpers.Combine(num, register.single_1.GetHashCode());
				num = HashHelpers.Combine(num, register.single_2.GetHashCode());
				return HashHelpers.Combine(num, register.single_3.GetHashCode());
			}
			if (typeof(T) == typeof(double))
			{
				num = HashHelpers.Combine(num, register.double_0.GetHashCode());
				return HashHelpers.Combine(num, register.double_1.GetHashCode());
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		public override string ToString()
		{
			return ToString("G", CultureInfo.CurrentCulture);
		}

		public string ToString(string format)
		{
			return ToString(format, CultureInfo.CurrentCulture);
		}

		public string ToString(string format, IFormatProvider formatProvider)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string numberGroupSeparator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator;
			stringBuilder.Append('<');
			for (int i = 0; i < Count - 1; i++)
			{
				stringBuilder.Append(((IFormattable)(object)this[i]).ToString(format, formatProvider));
				stringBuilder.Append(numberGroupSeparator);
				stringBuilder.Append(' ');
			}
			stringBuilder.Append(((IFormattable)(object)this[Count - 1]).ToString(format, formatProvider));
			stringBuilder.Append('>');
			return stringBuilder.ToString();
		}

		public unsafe static Vector<T>operator +(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)(uint)Count];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarAdd(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarAdd(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarAdd(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarAdd(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarAdd(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarAdd(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarAdd(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarAdd(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarAdd(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarAdd(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 + right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 + right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 + right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 + right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 + right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 + right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 + right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 + right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 + right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 + right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 + right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 + right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 + right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 + right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 + right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 + right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 + right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 + right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 + right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 + right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 + right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 + right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 + right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 + right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 + right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 + right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 + right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 + right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 + right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 + right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 + right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 + right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 + right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 + right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 + right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 + right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 + right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 + right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 + right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 + right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 + right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 + right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 + right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 + right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 + right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 + right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 + right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 + right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 + right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 + right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 + right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 + right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 + right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 + right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 + right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 + right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 + right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 + right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 + right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 + right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 + right.register.single_0;
				result.register.single_1 = left.register.single_1 + right.register.single_1;
				result.register.single_2 = left.register.single_2 + right.register.single_2;
				result.register.single_3 = left.register.single_3 + right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 + right.register.double_0;
				result.register.double_1 = left.register.double_1 + right.register.double_1;
			}
			return result;
		}

		public unsafe static Vector<T>operator -(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)(uint)Count];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarSubtract(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarSubtract(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarSubtract(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarSubtract(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarSubtract(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarSubtract(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarSubtract(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarSubtract(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarSubtract(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarSubtract(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 - right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 - right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 - right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 - right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 - right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 - right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 - right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 - right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 - right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 - right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 - right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 - right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 - right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 - right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 - right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 - right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 - right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 - right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 - right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 - right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 - right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 - right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 - right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 - right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 - right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 - right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 - right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 - right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 - right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 - right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 - right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 - right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 - right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 - right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 - right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 - right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 - right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 - right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 - right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 - right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 - right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 - right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 - right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 - right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 - right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 - right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 - right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 - right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 - right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 - right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 - right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 - right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 - right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 - right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 - right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 - right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 - right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 - right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 - right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 - right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 - right.register.single_0;
				result.register.single_1 = left.register.single_1 - right.register.single_1;
				result.register.single_2 = left.register.single_2 - right.register.single_2;
				result.register.single_3 = left.register.single_3 - right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 - right.register.double_0;
				result.register.double_1 = left.register.double_1 - right.register.double_1;
			}
			return result;
		}

		public unsafe static Vector<T>operator *(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)(uint)Count];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarMultiply(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarMultiply(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarMultiply(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarMultiply(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarMultiply(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarMultiply(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarMultiply(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarMultiply(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarMultiply(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarMultiply(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 * right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 * right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 * right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 * right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 * right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 * right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 * right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 * right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 * right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 * right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 * right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 * right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 * right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 * right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 * right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 * right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 * right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 * right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 * right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 * right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 * right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 * right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 * right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 * right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 * right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 * right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 * right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 * right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 * right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 * right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 * right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 * right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 * right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 * right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 * right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 * right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 * right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 * right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 * right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 * right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 * right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 * right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 * right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 * right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 * right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 * right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 * right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 * right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 * right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 * right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 * right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 * right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 * right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 * right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 * right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 * right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 * right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 * right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 * right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 * right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 * right.register.single_0;
				result.register.single_1 = left.register.single_1 * right.register.single_1;
				result.register.single_2 = left.register.single_2 * right.register.single_2;
				result.register.single_3 = left.register.single_3 * right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 * right.register.double_0;
				result.register.double_1 = left.register.double_1 * right.register.double_1;
			}
			return result;
		}

		public static Vector<T>operator *(Vector<T> value, T factor)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return new Vector<T>(factor) * value;
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(value.register.byte_0 * (byte)(object)factor);
				result.register.byte_1 = (byte)(value.register.byte_1 * (byte)(object)factor);
				result.register.byte_2 = (byte)(value.register.byte_2 * (byte)(object)factor);
				result.register.byte_3 = (byte)(value.register.byte_3 * (byte)(object)factor);
				result.register.byte_4 = (byte)(value.register.byte_4 * (byte)(object)factor);
				result.register.byte_5 = (byte)(value.register.byte_5 * (byte)(object)factor);
				result.register.byte_6 = (byte)(value.register.byte_6 * (byte)(object)factor);
				result.register.byte_7 = (byte)(value.register.byte_7 * (byte)(object)factor);
				result.register.byte_8 = (byte)(value.register.byte_8 * (byte)(object)factor);
				result.register.byte_9 = (byte)(value.register.byte_9 * (byte)(object)factor);
				result.register.byte_10 = (byte)(value.register.byte_10 * (byte)(object)factor);
				result.register.byte_11 = (byte)(value.register.byte_11 * (byte)(object)factor);
				result.register.byte_12 = (byte)(value.register.byte_12 * (byte)(object)factor);
				result.register.byte_13 = (byte)(value.register.byte_13 * (byte)(object)factor);
				result.register.byte_14 = (byte)(value.register.byte_14 * (byte)(object)factor);
				result.register.byte_15 = (byte)(value.register.byte_15 * (byte)(object)factor);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(value.register.sbyte_0 * (sbyte)(object)factor);
				result.register.sbyte_1 = (sbyte)(value.register.sbyte_1 * (sbyte)(object)factor);
				result.register.sbyte_2 = (sbyte)(value.register.sbyte_2 * (sbyte)(object)factor);
				result.register.sbyte_3 = (sbyte)(value.register.sbyte_3 * (sbyte)(object)factor);
				result.register.sbyte_4 = (sbyte)(value.register.sbyte_4 * (sbyte)(object)factor);
				result.register.sbyte_5 = (sbyte)(value.register.sbyte_5 * (sbyte)(object)factor);
				result.register.sbyte_6 = (sbyte)(value.register.sbyte_6 * (sbyte)(object)factor);
				result.register.sbyte_7 = (sbyte)(value.register.sbyte_7 * (sbyte)(object)factor);
				result.register.sbyte_8 = (sbyte)(value.register.sbyte_8 * (sbyte)(object)factor);
				result.register.sbyte_9 = (sbyte)(value.register.sbyte_9 * (sbyte)(object)factor);
				result.register.sbyte_10 = (sbyte)(value.register.sbyte_10 * (sbyte)(object)factor);
				result.register.sbyte_11 = (sbyte)(value.register.sbyte_11 * (sbyte)(object)factor);
				result.register.sbyte_12 = (sbyte)(value.register.sbyte_12 * (sbyte)(object)factor);
				result.register.sbyte_13 = (sbyte)(value.register.sbyte_13 * (sbyte)(object)factor);
				result.register.sbyte_14 = (sbyte)(value.register.sbyte_14 * (sbyte)(object)factor);
				result.register.sbyte_15 = (sbyte)(value.register.sbyte_15 * (sbyte)(object)factor);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(value.register.uint16_0 * (ushort)(object)factor);
				result.register.uint16_1 = (ushort)(value.register.uint16_1 * (ushort)(object)factor);
				result.register.uint16_2 = (ushort)(value.register.uint16_2 * (ushort)(object)factor);
				result.register.uint16_3 = (ushort)(value.register.uint16_3 * (ushort)(object)factor);
				result.register.uint16_4 = (ushort)(value.register.uint16_4 * (ushort)(object)factor);
				result.register.uint16_5 = (ushort)(value.register.uint16_5 * (ushort)(object)factor);
				result.register.uint16_6 = (ushort)(value.register.uint16_6 * (ushort)(object)factor);
				result.register.uint16_7 = (ushort)(value.register.uint16_7 * (ushort)(object)factor);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(value.register.int16_0 * (short)(object)factor);
				result.register.int16_1 = (short)(value.register.int16_1 * (short)(object)factor);
				result.register.int16_2 = (short)(value.register.int16_2 * (short)(object)factor);
				result.register.int16_3 = (short)(value.register.int16_3 * (short)(object)factor);
				result.register.int16_4 = (short)(value.register.int16_4 * (short)(object)factor);
				result.register.int16_5 = (short)(value.register.int16_5 * (short)(object)factor);
				result.register.int16_6 = (short)(value.register.int16_6 * (short)(object)factor);
				result.register.int16_7 = (short)(value.register.int16_7 * (short)(object)factor);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = value.register.uint32_0 * (uint)(object)factor;
				result.register.uint32_1 = value.register.uint32_1 * (uint)(object)factor;
				result.register.uint32_2 = value.register.uint32_2 * (uint)(object)factor;
				result.register.uint32_3 = value.register.uint32_3 * (uint)(object)factor;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = value.register.int32_0 * (int)(object)factor;
				result.register.int32_1 = value.register.int32_1 * (int)(object)factor;
				result.register.int32_2 = value.register.int32_2 * (int)(object)factor;
				result.register.int32_3 = value.register.int32_3 * (int)(object)factor;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = value.register.uint64_0 * (ulong)(object)factor;
				result.register.uint64_1 = value.register.uint64_1 * (ulong)(object)factor;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = value.register.int64_0 * (long)(object)factor;
				result.register.int64_1 = value.register.int64_1 * (long)(object)factor;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = value.register.single_0 * (float)(object)factor;
				result.register.single_1 = value.register.single_1 * (float)(object)factor;
				result.register.single_2 = value.register.single_2 * (float)(object)factor;
				result.register.single_3 = value.register.single_3 * (float)(object)factor;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = value.register.double_0 * (double)(object)factor;
				result.register.double_1 = value.register.double_1 * (double)(object)factor;
			}
			return result;
		}

		public static Vector<T>operator *(T factor, Vector<T> value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return new Vector<T>(factor) * value;
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(value.register.byte_0 * (byte)(object)factor);
				result.register.byte_1 = (byte)(value.register.byte_1 * (byte)(object)factor);
				result.register.byte_2 = (byte)(value.register.byte_2 * (byte)(object)factor);
				result.register.byte_3 = (byte)(value.register.byte_3 * (byte)(object)factor);
				result.register.byte_4 = (byte)(value.register.byte_4 * (byte)(object)factor);
				result.register.byte_5 = (byte)(value.register.byte_5 * (byte)(object)factor);
				result.register.byte_6 = (byte)(value.register.byte_6 * (byte)(object)factor);
				result.register.byte_7 = (byte)(value.register.byte_7 * (byte)(object)factor);
				result.register.byte_8 = (byte)(value.register.byte_8 * (byte)(object)factor);
				result.register.byte_9 = (byte)(value.register.byte_9 * (byte)(object)factor);
				result.register.byte_10 = (byte)(value.register.byte_10 * (byte)(object)factor);
				result.register.byte_11 = (byte)(value.register.byte_11 * (byte)(object)factor);
				result.register.byte_12 = (byte)(value.register.byte_12 * (byte)(object)factor);
				result.register.byte_13 = (byte)(value.register.byte_13 * (byte)(object)factor);
				result.register.byte_14 = (byte)(value.register.byte_14 * (byte)(object)factor);
				result.register.byte_15 = (byte)(value.register.byte_15 * (byte)(object)factor);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(value.register.sbyte_0 * (sbyte)(object)factor);
				result.register.sbyte_1 = (sbyte)(value.register.sbyte_1 * (sbyte)(object)factor);
				result.register.sbyte_2 = (sbyte)(value.register.sbyte_2 * (sbyte)(object)factor);
				result.register.sbyte_3 = (sbyte)(value.register.sbyte_3 * (sbyte)(object)factor);
				result.register.sbyte_4 = (sbyte)(value.register.sbyte_4 * (sbyte)(object)factor);
				result.register.sbyte_5 = (sbyte)(value.register.sbyte_5 * (sbyte)(object)factor);
				result.register.sbyte_6 = (sbyte)(value.register.sbyte_6 * (sbyte)(object)factor);
				result.register.sbyte_7 = (sbyte)(value.register.sbyte_7 * (sbyte)(object)factor);
				result.register.sbyte_8 = (sbyte)(value.register.sbyte_8 * (sbyte)(object)factor);
				result.register.sbyte_9 = (sbyte)(value.register.sbyte_9 * (sbyte)(object)factor);
				result.register.sbyte_10 = (sbyte)(value.register.sbyte_10 * (sbyte)(object)factor);
				result.register.sbyte_11 = (sbyte)(value.register.sbyte_11 * (sbyte)(object)factor);
				result.register.sbyte_12 = (sbyte)(value.register.sbyte_12 * (sbyte)(object)factor);
				result.register.sbyte_13 = (sbyte)(value.register.sbyte_13 * (sbyte)(object)factor);
				result.register.sbyte_14 = (sbyte)(value.register.sbyte_14 * (sbyte)(object)factor);
				result.register.sbyte_15 = (sbyte)(value.register.sbyte_15 * (sbyte)(object)factor);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(value.register.uint16_0 * (ushort)(object)factor);
				result.register.uint16_1 = (ushort)(value.register.uint16_1 * (ushort)(object)factor);
				result.register.uint16_2 = (ushort)(value.register.uint16_2 * (ushort)(object)factor);
				result.register.uint16_3 = (ushort)(value.register.uint16_3 * (ushort)(object)factor);
				result.register.uint16_4 = (ushort)(value.register.uint16_4 * (ushort)(object)factor);
				result.register.uint16_5 = (ushort)(value.register.uint16_5 * (ushort)(object)factor);
				result.register.uint16_6 = (ushort)(value.register.uint16_6 * (ushort)(object)factor);
				result.register.uint16_7 = (ushort)(value.register.uint16_7 * (ushort)(object)factor);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(value.register.int16_0 * (short)(object)factor);
				result.register.int16_1 = (short)(value.register.int16_1 * (short)(object)factor);
				result.register.int16_2 = (short)(value.register.int16_2 * (short)(object)factor);
				result.register.int16_3 = (short)(value.register.int16_3 * (short)(object)factor);
				result.register.int16_4 = (short)(value.register.int16_4 * (short)(object)factor);
				result.register.int16_5 = (short)(value.register.int16_5 * (short)(object)factor);
				result.register.int16_6 = (short)(value.register.int16_6 * (short)(object)factor);
				result.register.int16_7 = (short)(value.register.int16_7 * (short)(object)factor);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = value.register.uint32_0 * (uint)(object)factor;
				result.register.uint32_1 = value.register.uint32_1 * (uint)(object)factor;
				result.register.uint32_2 = value.register.uint32_2 * (uint)(object)factor;
				result.register.uint32_3 = value.register.uint32_3 * (uint)(object)factor;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = value.register.int32_0 * (int)(object)factor;
				result.register.int32_1 = value.register.int32_1 * (int)(object)factor;
				result.register.int32_2 = value.register.int32_2 * (int)(object)factor;
				result.register.int32_3 = value.register.int32_3 * (int)(object)factor;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = value.register.uint64_0 * (ulong)(object)factor;
				result.register.uint64_1 = value.register.uint64_1 * (ulong)(object)factor;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = value.register.int64_0 * (long)(object)factor;
				result.register.int64_1 = value.register.int64_1 * (long)(object)factor;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = value.register.single_0 * (float)(object)factor;
				result.register.single_1 = value.register.single_1 * (float)(object)factor;
				result.register.single_2 = value.register.single_2 * (float)(object)factor;
				result.register.single_3 = value.register.single_3 * (float)(object)factor;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = value.register.double_0 * (double)(object)factor;
				result.register.double_1 = value.register.double_1 * (double)(object)factor;
			}
			return result;
		}

		public unsafe static Vector<T>operator /(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)(uint)Count];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarDivide(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarDivide(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarDivide(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarDivide(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarDivide(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarDivide(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarDivide(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarDivide(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarDivide(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarDivide(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 / right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 / right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 / right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 / right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 / right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 / right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 / right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 / right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 / right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 / right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 / right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 / right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 / right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 / right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 / right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 / right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 / right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 / right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 / right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 / right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 / right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 / right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 / right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 / right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 / right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 / right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 / right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 / right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 / right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 / right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 / right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 / right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 / right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 / right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 / right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 / right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 / right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 / right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 / right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 / right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 / right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 / right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 / right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 / right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 / right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 / right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 / right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 / right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 / right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 / right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 / right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 / right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 / right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 / right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 / right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 / right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 / right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 / right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 / right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 / right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 / right.register.single_0;
				result.register.single_1 = left.register.single_1 / right.register.single_1;
				result.register.single_2 = left.register.single_2 / right.register.single_2;
				result.register.single_3 = left.register.single_3 / right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 / right.register.double_0;
				result.register.double_1 = left.register.double_1 / right.register.double_1;
			}
			return result;
		}

		public static Vector<T>operator -(Vector<T> value)
		{
			return Zero - value;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public unsafe static Vector<T>operator &(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] & ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 & right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 & right.register.int64_1;
			}
			return result;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public unsafe static Vector<T>operator |(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] | ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 | right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 | right.register.int64_1;
			}
			return result;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public unsafe static Vector<T>operator ^(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] ^ ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 ^ right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 ^ right.register.int64_1;
			}
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector<T>operator ~(Vector<T> value)
		{
			return s_allOnes ^ value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator ==(Vector<T> left, Vector<T> right)
		{
			return left.Equals(right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator !=(Vector<T> left, Vector<T> right)
		{
			return !(left == right);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<byte>(Vector<T> value)
		{
			return new Vector<byte>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<sbyte>(Vector<T> value)
		{
			return new Vector<sbyte>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<ushort>(Vector<T> value)
		{
			return new Vector<ushort>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<short>(Vector<T> value)
		{
			return new Vector<short>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<uint>(Vector<T> value)
		{
			return new Vector<uint>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<int>(Vector<T> value)
		{
			return new Vector<int>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<ulong>(Vector<T> value)
		{
			return new Vector<ulong>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<long>(Vector<T> value)
		{
			return new Vector<long>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<float>(Vector<T> value)
		{
			return new Vector<float>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<double>(Vector<T> value)
		{
			return new Vector<double>(ref value.register);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Compile

System.Runtime.CompilerServices.Unsafe.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;

[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: CLSCompliant(false)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyDescription("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyFileVersion("6.0.21.52210")]
[assembly: AssemblyInformationalVersion("6.0.0")]
[assembly: AssemblyTitle("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyVersion("6.0.0.0")]
namespace System.Runtime.CompilerServices
{
	public static class Unsafe
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T Read<T>(void* source)
		{
			return Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T ReadUnaligned<T>(void* source)
		{
			return Unsafe.ReadUnaligned<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T ReadUnaligned<T>(ref byte source)
		{
			return Unsafe.ReadUnaligned<T>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Write<T>(void* destination, T value)
		{
			Unsafe.Write(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void WriteUnaligned<T>(void* destination, T value)
		{
			Unsafe.WriteUnaligned(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void WriteUnaligned<T>(ref byte destination, T value)
		{
			Unsafe.WriteUnaligned(ref destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(void* destination, ref T source)
		{
			Unsafe.Write(destination, source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(ref T destination, void* source)
		{
			destination = Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* AsPointer<T>(ref T value)
		{
			return Unsafe.AsPointer(ref value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void SkipInit<T>(out T value)
		{
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static int SizeOf<T>()
		{
			return Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlock(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlock(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlock(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T As<T>(object o) where T : class
		{
			return (T)o;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static ref T AsRef<T>(void* source)
		{
			return ref *(T*)source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AsRef<T>(in T source)
		{
			return ref source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref TTo As<TFrom, TTo>(ref TFrom source)
		{
			return ref Unsafe.As<TFrom, TTo>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Unbox<T>(object box) where T : struct
		{
			return ref (T)box;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Add<T>(void* source, int elementOffset)
		{
			return (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T Add<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AddByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.AddByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T AddByteOffset<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint byteOffset)
		{
			return ref Unsafe.AddByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Subtract<T>(void* source, int elementOffset)
		{
			return (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T Subtract<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T SubtractByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T SubtractByteOffset<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint byteOffset)
		{
			return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static IntPtr ByteOffset<T>(ref T origin, ref T target)
		{
			return Unsafe.ByteOffset(target: ref target, origin: ref origin);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool AreSame<T>(ref T left, ref T right)
		{
			return Unsafe.AreSame(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressGreaterThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressGreaterThan(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressLessThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressLessThan(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static bool IsNullRef<T>(ref T source)
		{
			return Unsafe.AsPointer(ref source) == null;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static ref T NullRef<T>()
		{
			return ref *(T*)null;
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class NonVersionableAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	[Microsoft.CodeAnalysis.Embedded]
	[CompilerGenerated]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] A_0)
		{
			TransformFlags = A_0;
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}

System.Threading.Tasks.Extensions.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading.Tasks;
using System.Threading.Tasks.Sources;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("System.Threading.Tasks.Extensions")]
[assembly: AssemblyDescription("System.Threading.Tasks.Extensions")]
[assembly: AssemblyDefaultAlias("System.Threading.Tasks.Extensions")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.28619.01")]
[assembly: AssemblyInformationalVersion("4.6.28619.01 @BuiltBy: dlab14-DDVSOWINAGE069 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/7601f4f6225089ffb291dc7d58293c7bbf5c5d4f")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyVersion("4.2.0.1")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}
namespace System
{
	internal static class ThrowHelper
	{
		internal static void ThrowArgumentNullException(System.ExceptionArgument argument)
		{
			throw GetArgumentNullException(argument);
		}

		internal static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			throw GetArgumentOutOfRangeException(argument);
		}

		private static ArgumentNullException GetArgumentNullException(System.ExceptionArgument argument)
		{
			return new ArgumentNullException(GetArgumentName(argument));
		}

		private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			return new ArgumentOutOfRangeException(GetArgumentName(argument));
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static string GetArgumentName(System.ExceptionArgument argument)
		{
			return argument.ToString();
		}
	}
	internal enum ExceptionArgument
	{
		task,
		source,
		state
	}
}
namespace System.Threading.Tasks
{
	[StructLayout(LayoutKind.Auto)]
	[AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder))]
	public readonly struct ValueTask : IEquatable<ValueTask>
	{
		private sealed class ValueTaskSourceAsTask : TaskCompletionSource<bool>
		{
			private static readonly Action<object> s_completionAction = delegate(object state)
			{
				IValueTaskSource source;
				if (!(state is ValueTaskSourceAsTask valueTaskSourceAsTask) || (source = valueTaskSourceAsTask._source) == null)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.state);
					return;
				}
				valueTaskSourceAsTask._source = null;
				ValueTaskSourceStatus status = source.GetStatus(valueTaskSourceAsTask._token);
				try
				{
					source.GetResult(valueTaskSourceAsTask._token);
					valueTaskSourceAsTask.TrySetResult(result: false);
				}
				catch (Exception exception)
				{
					if (status == ValueTaskSourceStatus.Canceled)
					{
						valueTaskSourceAsTask.TrySetCanceled();
					}
					else
					{
						valueTaskSourceAsTask.TrySetException(exception);
					}
				}
			};

			private IValueTaskSource _source;

			private readonly short _token;

			public ValueTaskSourceAsTask(IValueTaskSource source, short token)
			{
				_token = token;
				_source = source;
				source.OnCompleted(s_completionAction, this, token, ValueTaskSourceOnCompletedFlags.None);
			}
		}

		private static readonly Task s_canceledTask = Task.Delay(-1, new CancellationToken(canceled: true));

		internal readonly object _obj;

		internal readonly short _token;

		internal readonly bool _continueOnCapturedContext;

		internal static Task CompletedTask { get; } = Task.Delay(0);


		public bool IsCompleted
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				object obj = _obj;
				if (obj == null)
				{
					return true;
				}
				if (obj is Task task)
				{
					return task.IsCompleted;
				}
				return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) != ValueTaskSourceStatus.Pending;
			}
		}

		public bool IsCompletedSuccessfully
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				object obj = _obj;
				if (obj == null)
				{
					return true;
				}
				if (obj is Task task)
				{
					return task.Status == TaskStatus.RanToCompletion;
				}
				return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) == ValueTaskSourceStatus.Succeeded;
			}
		}

		public bool IsFaulted
		{
			get
			{
				object obj = _obj;
				if (obj == null)
				{
					return false;
				}
				if (obj is Task task)
				{
					return task.IsFaulted;
				}
				return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) == ValueTaskSourceStatus.Faulted;
			}
		}

		public bool IsCanceled
		{
			get
			{
				object obj = _obj;
				if (obj == null)
				{
					return false;
				}
				if (obj is Task task)
				{
					return task.IsCanceled;
				}
				return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) == ValueTaskSourceStatus.Canceled;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ValueTask(Task task)
		{
			if (task == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.task);
			}
			_obj = task;
			_continueOnCapturedContext = true;
			_token = 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ValueTask(IValueTaskSource source, short token)
		{
			if (source == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.source);
			}
			_obj = source;
			_token = token;
			_continueOnCapturedContext = true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private ValueTask(object obj, short token, bool continueOnCapturedContext)
		{
			_obj = obj;
			_token = token;
			_continueOnCapturedContext = continueOnCapturedContext;
		}

		public override int GetHashCode()
		{
			return _obj?.GetHashCode() ?? 0;
		}

		public override bool Equals(object obj)
		{
			if (obj is ValueTask)
			{
				return Equals((ValueTask)obj);
			}
			return false;
		}

		public bool Equals(ValueTask other)
		{
			if (_obj == other._obj)
			{
				return _token == other._token;
			}
			return false;
		}

		public static bool operator ==(ValueTask left, ValueTask right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(ValueTask left, ValueTask right)
		{
			return !left.Equals(right);
		}

		public Task AsTask()
		{
			object obj = _obj;
			object obj2;
			if (obj != null)
			{
				obj2 = obj as Task;
				if (obj2 == null)
				{
					return GetTaskForValueTaskSource(System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj));
				}
			}
			else
			{
				obj2 = CompletedTask;
			}
			return (Task)obj2;
		}

		public ValueTask Preserve()
		{
			if (_obj != null)
			{
				return new ValueTask(AsTask());
			}
			return this;
		}

		private Task GetTaskForValueTaskSource(IValueTaskSource t)
		{
			ValueTaskSourceStatus status = t.GetStatus(_token);
			if (status != 0)
			{
				try
				{
					t.GetResult(_token);
					return CompletedTask;
				}
				catch (Exception exception)
				{
					if (status == ValueTaskSourceStatus.Canceled)
					{
						return s_canceledTask;
					}
					TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>();
					taskCompletionSource.TrySetException(exception);
					return taskCompletionSource.Task;
				}
			}
			ValueTaskSourceAsTask valueTaskSourceAsTask = new ValueTaskSourceAsTask(t, _token);
			return valueTaskSourceAsTask.Task;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[StackTraceHidden]
		internal void ThrowIfCompletedUnsuccessfully()
		{
			object obj = _obj;
			if (obj != null)
			{
				if (obj is Task task)
				{
					task.GetAwaiter().GetResult();
				}
				else
				{
					System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).GetResult(_token);
				}
			}
		}

		public ValueTaskAwaiter GetAwaiter()
		{
			return new ValueTaskAwaiter(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ConfiguredValueTaskAwaitable ConfigureAwait(bool continueOnCapturedContext)
		{
			return new ConfiguredValueTaskAwaitable(new ValueTask(_obj, _token, continueOnCapturedContext));
		}
	}
	[StructLayout(LayoutKind.Auto)]
	[AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder<>))]
	public readonly struct ValueTask<TResult> : IEquatable<ValueTask<TResult>>
	{
		private sealed class ValueTaskSourceAsTask : TaskCompletionSource<TResult>
		{
			private static readonly Action<object> s_completionAction = delegate(object state)
			{
				IValueTaskSource<TResult> source;
				if (!(state is ValueTaskSourceAsTask valueTaskSourceAsTask) || (source = valueTaskSourceAsTask._source) == null)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.state);
					return;
				}
				valueTaskSourceAsTask._source = null;
				ValueTaskSourceStatus status = source.GetStatus(valueTaskSourceAsTask._token);
				try
				{
					valueTaskSourceAsTask.TrySetResult(source.GetResult(valueTaskSourceAsTask._token));
				}
				catch (Exception exception)
				{
					if (status == ValueTaskSourceStatus.Canceled)
					{
						valueTaskSourceAsTask.TrySetCanceled();
					}
					else
					{
						valueTaskSourceAsTask.TrySetException(exception);
					}
				}
			};

			private IValueTaskSource<TResult> _source;

			private readonly short _token;

			public ValueTaskSourceAsTask(IValueTaskSource<TResult> source, short token)
			{
				_source = source;
				_token = token;
				source.OnCompleted(s_completionAction, this, token, ValueTaskSourceOnCompletedFlags.None);
			}
		}

		private static Task<TResult> s_canceledTask;

		internal readonly object _obj;

		internal readonly TResult _result;

		internal readonly short _token;

		internal readonly bool _continueOnCapturedContext;

		public bool IsCompleted
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				object obj = _obj;
				if (obj == null)
				{
					return true;
				}
				if (obj is Task<TResult> task)
				{
					return task.IsCompleted;
				}
				return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).GetStatus(_token) != ValueTaskSourceStatus.Pending;
			}
		}

		public bool IsCompletedSuccessfully
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				object obj = _obj;
				if (obj == null)
				{
					return true;
				}
				if (obj is Task<TResult> task)
				{
					return task.Status == TaskStatus.RanToCompletion;
				}
				return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).GetStatus(_token) == ValueTaskSourceStatus.Succeeded;
			}
		}

		public bool IsFaulted
		{
			get
			{
				object obj = _obj;
				if (obj == null)
				{
					return false;
				}
				if (obj is Task<TResult> task)
				{
					return task.IsFaulted;
				}
				return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).GetStatus(_token) == ValueTaskSourceStatus.Faulted;
			}
		}

		public bool IsCanceled
		{
			get
			{
				object obj = _obj;
				if (obj == null)
				{
					return false;
				}
				if (obj is Task<TResult> task)
				{
					return task.IsCanceled;
				}
				return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).GetStatus(_token) == ValueTaskSourceStatus.Canceled;
			}
		}

		public TResult Result
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				object obj = _obj;
				if (obj == null)
				{
					return _result;
				}
				if (obj is Task<TResult> task)
				{
					return task.GetAwaiter().GetResult();
				}
				return System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).GetResult(_token);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ValueTask(TResult result)
		{
			_result = result;
			_obj = null;
			_continueOnCapturedContext = true;
			_token = 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ValueTask(Task<TResult> task)
		{
			if (task == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.task);
			}
			_obj = task;
			_result = default(TResult);
			_continueOnCapturedContext = true;
			_token = 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ValueTask(IValueTaskSource<TResult> source, short token)
		{
			if (source == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.source);
			}
			_obj = source;
			_token = token;
			_result = default(TResult);
			_continueOnCapturedContext = true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private ValueTask(object obj, TResult result, short token, bool continueOnCapturedContext)
		{
			_obj = obj;
			_result = result;
			_token = token;
			_continueOnCapturedContext = continueOnCapturedContext;
		}

		public override int GetHashCode()
		{
			if (_obj == null)
			{
				if (_result == null)
				{
					return 0;
				}
				return _result.GetHashCode();
			}
			return _obj.GetHashCode();
		}

		public override bool Equals(object obj)
		{
			if (obj is ValueTask<TResult>)
			{
				return Equals((ValueTask<TResult>)obj);
			}
			return false;
		}

		public bool Equals(ValueTask<TResult> other)
		{
			if (_obj == null && other._obj == null)
			{
				return EqualityComparer<TResult>.Default.Equals(_result, other._result);
			}
			if (_obj == other._obj)
			{
				return _token == other._token;
			}
			return false;
		}

		public static bool operator ==(ValueTask<TResult> left, ValueTask<TResult> right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(ValueTask<TResult> left, ValueTask<TResult> right)
		{
			return !left.Equals(right);
		}

		public Task<TResult> AsTask()
		{
			object obj = _obj;
			if (obj == null)
			{
				return Task.FromResult(_result);
			}
			if (obj is Task<TResult> result)
			{
				return result;
			}
			return GetTaskForValueTaskSource(System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj));
		}

		public ValueTask<TResult> Preserve()
		{
			if (_obj != null)
			{
				return new ValueTask<TResult>(AsTask());
			}
			return this;
		}

		private Task<TResult> GetTaskForValueTaskSource(IValueTaskSource<TResult> t)
		{
			ValueTaskSourceStatus status = t.GetStatus(_token);
			if (status != 0)
			{
				try
				{
					return Task.FromResult(t.GetResult(_token));
				}
				catch (Exception exception)
				{
					if (status == ValueTaskSourceStatus.Canceled)
					{
						Task<TResult> task = s_canceledTask;
						if (task == null)
						{
							TaskCompletionSource<TResult> taskCompletionSource = new TaskCompletionSource<TResult>();
							taskCompletionSource.TrySetCanceled();
							task = (s_canceledTask = taskCompletionSource.Task);
						}
						return task;
					}
					TaskCompletionSource<TResult> taskCompletionSource2 = new TaskCompletionSource<TResult>();
					taskCompletionSource2.TrySetException(exception);
					return taskCompletionSource2.Task;
				}
			}
			ValueTaskSourceAsTask valueTaskSourceAsTask = new ValueTaskSourceAsTask(t, _token);
			return valueTaskSourceAsTask.Task;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ValueTaskAwaiter<TResult> GetAwaiter()
		{
			return new ValueTaskAwaiter<TResult>(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ConfiguredValueTaskAwaitable<TResult> ConfigureAwait(bool continueOnCapturedContext)
		{
			return new ConfiguredValueTaskAwaitable<TResult>(new ValueTask<TResult>(_obj, _result, _token, continueOnCapturedContext));
		}

		public override string ToString()
		{
			if (IsCompletedSuccessfully)
			{
				TResult result = Result;
				if (result != null)
				{
					return result.ToString();
				}
			}
			return string.Empty;
		}
	}
}
namespace System.Threading.Tasks.Sources
{
	[Flags]
	public enum ValueTaskSourceOnCompletedFlags
	{
		None = 0,
		UseSchedulingContext = 1,
		FlowExecutionContext = 2
	}
	public enum ValueTaskSourceStatus
	{
		Pending,
		Succeeded,
		Faulted,
		Canceled
	}
	public interface IValueTaskSource
	{
		ValueTaskSourceStatus GetStatus(short token);

		void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags);

		void GetResult(short token);
	}
	public interface IValueTaskSource<out TResult>
	{
		ValueTaskSourceStatus GetStatus(short token);

		void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags);

		TResult GetResult(short token);
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
	public sealed class AsyncMethodBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public AsyncMethodBuilderAttribute(Type builderType)
		{
			BuilderType = builderType;
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public struct AsyncValueTaskMethodBuilder
	{
		private AsyncTaskMethodBuilder _methodBuilder;

		private bool _haveResult;

		private bool _useBuilder;

		public ValueTask Task
		{
			get
			{
				if (_haveResult)
				{
					return default(ValueTask);
				}
				_useBuilder = true;
				return new ValueTask(_methodBuilder.Task);
			}
		}

		public static AsyncValueTaskMethodBuilder Create()
		{
			return default(AsyncValueTaskMethodBuilder);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
		{
			_methodBuilder.Start(ref stateMachine);
		}

		public void SetStateMachine(IAsyncStateMachine stateMachine)
		{
			_methodBuilder.SetStateMachine(stateMachine);
		}

		public void SetResult()
		{
			if (_useBuilder)
			{
				_methodBuilder.SetResult();
			}
			else
			{
				_haveResult = true;
			}
		}

		public void SetException(Exception exception)
		{
			_methodBuilder.SetException(exception);
		}

		public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
		{
			_useBuilder = true;
			_methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
		}

		[SecuritySafeCritical]
		public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
		{
			_useBuilder = true;
			_methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public struct AsyncValueTaskMethodBuilder<TResult>
	{
		private AsyncTaskMethodBuilder<TResult> _methodBuilder;

		private TResult _result;

		private bool _haveResult;

		private bool _useBuilder;

		public ValueTask<TResult> Task
		{
			get
			{
				if (_haveResult)
				{
					return new ValueTask<TResult>(_result);
				}
				_useBuilder = true;
				return new ValueTask<TResult>(_methodBuilder.Task);
			}
		}

		public static AsyncValueTaskMethodBuilder<TResult> Create()
		{
			return default(AsyncValueTaskMethodBuilder<TResult>);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
		{
			_methodBuilder.Start(ref stateMachine);
		}

		public void SetStateMachine(IAsyncStateMachine stateMachine)
		{
			_methodBuilder.SetStateMachine(stateMachine);
		}

		public void SetResult(TResult result)
		{
			if (_useBuilder)
			{
				_methodBuilder.SetResult(result);
				return;
			}
			_result = result;
			_haveResult = true;
		}

		public void SetException(Exception exception)
		{
			_methodBuilder.SetException(exception);
		}

		public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
		{
			_useBuilder = true;
			_methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
		}

		[SecuritySafeCritical]
		public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
		{
			_useBuilder = true;
			_methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public readonly struct ConfiguredValueTaskAwaitable
	{
		[StructLayout(LayoutKind.Auto)]
		public readonly struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion
		{
			private readonly ValueTask _value;

			public bool IsCompleted
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return _value.IsCompleted;
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal ConfiguredValueTaskAwaiter(ValueTask value)
			{
				_value = value;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			[StackTraceHidden]
			public void GetResult()
			{
				_value.ThrowIfCompletedUnsuccessfully();
			}

			public void OnCompleted(Action continuation)
			{
				object obj = _value._obj;
				if (obj is Task task)
				{
					task.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation);
				}
				else if (obj != null)
				{
					System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.FlowExecutionContext | (_value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None));
				}
				else
				{
					ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation);
				}
			}

			public void UnsafeOnCompleted(Action continuation)
			{
				object obj = _value._obj;
				if (obj is Task task)
				{
					task.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation);
				}
				else if (obj != null)
				{
					System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, _value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None);
				}
				else
				{
					ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation);
				}
			}
		}

		private readonly ValueTask _value;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ConfiguredValueTaskAwaitable(ValueTask value)
		{
			_value = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ConfiguredValueTaskAwaiter GetAwaiter()
		{
			return new ConfiguredValueTaskAwaiter(_value);
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public readonly struct ConfiguredValueTaskAwaitable<TResult>
	{
		[StructLayout(LayoutKind.Auto)]
		public readonly struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion
		{
			private readonly ValueTask<TResult> _value;

			public bool IsCompleted
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return _value.IsCompleted;
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal ConfiguredValueTaskAwaiter(ValueTask<TResult> value)
			{
				_value = value;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			[StackTraceHidden]
			public TResult GetResult()
			{
				return _value.Result;
			}

			public void OnCompleted(Action continuation)
			{
				object obj = _value._obj;
				if (obj is Task<TResult> task)
				{
					task.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation);
				}
				else if (obj != null)
				{
					System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.FlowExecutionContext | (_value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None));
				}
				else
				{
					ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().OnCompleted(continuation);
				}
			}

			public void UnsafeOnCompleted(Action continuation)
			{
				object obj = _value._obj;
				if (obj is Task<TResult> task)
				{
					task.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation);
				}
				else if (obj != null)
				{
					System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, _value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None);
				}
				else
				{
					ValueTask.CompletedTask.ConfigureAwait(_value._continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation);
				}
			}
		}

		private readonly ValueTask<TResult> _value;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ConfiguredValueTaskAwaitable(ValueTask<TResult> value)
		{
			_value = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ConfiguredValueTaskAwaiter GetAwaiter()
		{
			return new ConfiguredValueTaskAwaiter(_value);
		}
	}
	public readonly struct ValueTaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion
	{
		internal static readonly Action<object> s_invokeActionDelegate = delegate(object state)
		{
			if (!(state is Action action))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.state);
			}
			else
			{
				action();
			}
		};

		private readonly ValueTask _value;

		public bool IsCompleted
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return _value.IsCompleted;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ValueTaskAwaiter(ValueTask value)
		{
			_value = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[StackTraceHidden]
		public void GetResult()
		{
			_value.ThrowIfCompletedUnsuccessfully();
		}

		public void OnCompleted(Action continuation)
		{
			object obj = _value._obj;
			if (obj is Task task)
			{
				task.GetAwaiter().OnCompleted(continuation);
			}
			else if (obj != null)
			{
				System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).OnCompleted(s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext | ValueTaskSourceOnCompletedFlags.FlowExecutionContext);
			}
			else
			{
				ValueTask.CompletedTask.GetAwaiter().OnCompleted(continuation);
			}
		}

		public void UnsafeOnCompleted(Action continuation)
		{
			object obj = _value._obj;
			if (obj is Task task)
			{
				task.GetAwaiter().UnsafeOnCompleted(continuation);
			}
			else if (obj != null)
			{
				System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource>(obj).OnCompleted(s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext);
			}
			else
			{
				ValueTask.CompletedTask.GetAwaiter().UnsafeOnCompleted(continuation);
			}
		}
	}
	public readonly struct ValueTaskAwaiter<TResult> : ICriticalNotifyCompletion, INotifyCompletion
	{
		private readonly ValueTask<TResult> _value;

		public bool IsCompleted
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return _value.IsCompleted;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ValueTaskAwaiter(ValueTask<TResult> value)
		{
			_value = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[StackTraceHidden]
		public TResult GetResult()
		{
			return _value.Result;
		}

		public void OnCompleted(Action continuation)
		{
			object obj = _value._obj;
			if (obj is Task<TResult> task)
			{
				task.GetAwaiter().OnCompleted(continuation);
			}
			else if (obj != null)
			{
				System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext | ValueTaskSourceOnCompletedFlags.FlowExecutionContext);
			}
			else
			{
				ValueTask.CompletedTask.GetAwaiter().OnCompleted(continuation);
			}
		}

		public void UnsafeOnCompleted(Action continuation)
		{
			object obj = _value._obj;
			if (obj is Task<TResult> task)
			{
				task.GetAwaiter().UnsafeOnCompleted(continuation);
			}
			else if (obj != null)
			{
				System.Runtime.CompilerServices.Unsafe.As<IValueTaskSource<TResult>>(obj).OnCompleted(ValueTaskAwaiter.s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext);
			}
			else
			{
				ValueTask.CompletedTask.GetAwaiter().UnsafeOnCompleted(continuation);
			}
		}
	}
}
namespace System.Diagnostics
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
	internal sealed class StackTraceHiddenAttribute : Attribute
	{
	}
}

websocket-sharp.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Timers;
using WebSocketSharp.Net;
using WebSocketSharp.Net.WebSockets;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("websocket-sharp")]
[assembly: AssemblyDescription("A C# implementation of the WebSocket protocol client and server")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("websocket-sharp.dll")]
[assembly: AssemblyCopyright("sta.blockhead")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.0.2.24918")]
namespace WebSocketSharp
{
	public static class Ext
	{
		private static readonly byte[] _last = new byte[1];

		private static readonly int _maxRetry = 5;

		private const string _tspecials = "()<>@,;:\\\"/[]?={} \t";

		private static byte[] compress(this byte[] data)
		{
			if (data.LongLength == 0)
			{
				return data;
			}
			using MemoryStream stream = new MemoryStream(data);
			return stream.compressToArray();
		}

		private static MemoryStream compress(this Stream stream)
		{
			MemoryStream memoryStream = new MemoryStream();
			if (stream.Length == 0)
			{
				return memoryStream;
			}
			stream.Position = 0L;
			CompressionMode mode = CompressionMode.Compress;
			using DeflateStream deflateStream = new DeflateStream(memoryStream, mode, leaveOpen: true);
			CopyTo(stream, deflateStream, 1024);
			deflateStream.Close();
			memoryStream.Write(_last, 0, 1);
			memoryStream.Position = 0L;
			return memoryStream;
		}

		private static byte[] compressToArray(this Stream stream)
		{
			using MemoryStream memoryStream = stream.compress();
			memoryStream.Close();
			return memoryStream.ToArray();
		}

		private static byte[] decompress(this byte[] data)
		{
			if (data.LongLength == 0)
			{
				return data;
			}
			using MemoryStream stream = new MemoryStream(data);
			return stream.decompressToArray();
		}

		private static MemoryStream decompress(this Stream stream)
		{
			MemoryStream memoryStream = new MemoryStream();
			if (stream.Length == 0)
			{
				return memoryStream;
			}
			stream.Position = 0L;
			CompressionMode mode = CompressionMode.Decompress;
			using DeflateStream sourceStream = new DeflateStream(stream, mode, leaveOpen: true);
			CopyTo(sourceStream, memoryStream, 1024);
			memoryStream.Position = 0L;
			return memoryStream;
		}

		private static byte[] decompressToArray(this Stream stream)
		{
			using MemoryStream memoryStream = stream.decompress();
			memoryStream.Close();
			return memoryStream.ToArray();
		}

		private static bool isPredefinedScheme(this string value)
		{
			switch (value[0])
			{
			case 'h':
				return value == "http" || value == "https";
			case 'w':
				return value == "ws" || value == "wss";
			case 'f':
				return value == "file" || value == "ftp";
			case 'g':
				return value == "gopher";
			case 'm':
				return value == "mailto";
			case 'n':
			{
				char c = value[1];
				return (c != 'e') ? (value == "nntp") : (value == "news" || value == "net.pipe" || value == "net.tcp");
			}
			default:
				return false;
			}
		}

		internal static byte[] Append(this ushort code, string reason)
		{
			byte[] array = code.ToByteArray(ByteOrder.Big);
			if (reason == null || reason.Length == 0)
			{
				return array;
			}
			List<byte> list = new List<byte>(array);
			byte[] bytes = Encoding.UTF8.GetBytes(reason);
			list.AddRange(bytes);
			return list.ToArray();
		}

		internal static byte[] Compress(this byte[] data, CompressionMethod method)
		{
			return (method == CompressionMethod.Deflate) ? data.compress() : data;
		}

		internal static Stream Compress(this Stream stream, CompressionMethod method)
		{
			return (method == CompressionMethod.Deflate) ? stream.compress() : stream;
		}

		internal static bool Contains(this string value, params char[] anyOf)
		{
			return anyOf != null && anyOf.Length != 0 && value.IndexOfAny(anyOf) > -1;
		}

		internal static bool Contains(this NameValueCollection collection, string name)
		{
			return collection[name] != null;
		}

		internal static bool Contains(this NameValueCollection collection, string name, string value, StringComparison comparisonTypeForValue)
		{
			string text = collection[name];
			if (text == null)
			{
				return false;
			}
			string[] array = text.Split(new char[1] { ',' });
			foreach (string text2 in array)
			{
				if (text2.Trim().Equals(value, comparisonTypeForValue))
				{
					return true;
				}
			}
			return false;
		}

		internal static bool Contains<T>(this IEnumerable<T> source, Func<T, bool> condition)
		{
			foreach (T item in source)
			{
				if (condition(item))
				{
					return true;
				}
			}
			return false;
		}

		internal static bool ContainsTwice(this string[] values)
		{
			int len = values.Length;
			int end = len - 1;
			Func<int, bool> seek = null;
			seek = delegate(int idx)
			{
				if (idx == end)
				{
					return false;
				}
				string text = values[idx];
				for (int i = idx + 1; i < len; i++)
				{
					if (values[i] == text)
					{
						return true;
					}
				}
				return seek(++idx);
			};
			return seek(0);
		}

		internal static T[] Copy<T>(this T[] sourceArray, int length)
		{
			T[] array = new T[length];
			Array.Copy(sourceArray, 0, array, 0, length);
			return array;
		}

		internal static T[] Copy<T>(this T[] sourceArray, long length)
		{
			T[] array = new T[length];
			Array.Copy(sourceArray, 0L, array, 0L, length);
			return array;
		}

		internal static void CopyTo(this Stream sourceStream, Stream destinationStream, int bufferLength)
		{
			byte[] buffer = new byte[bufferLength];
			while (true)
			{
				int num = sourceStream.Read(buffer, 0, bufferLength);
				if (num <= 0)
				{
					break;
				}
				destinationStream.Write(buffer, 0, num);
			}
		}

		internal static void CopyToAsync(this Stream sourceStream, Stream destinationStream, int bufferLength, Action completed, Action<Exception> error)
		{
			byte[] buff = new byte[bufferLength];
			AsyncCallback callback = null;
			callback = delegate(IAsyncResult ar)
			{
				try
				{
					int num = sourceStream.EndRead(ar);
					if (num <= 0)
					{
						if (completed != null)
						{
							completed();
						}
					}
					else
					{
						destinationStream.Write(buff, 0, num);
						sourceStream.BeginRead(buff, 0, bufferLength, callback, null);
					}
				}
				catch (Exception obj2)
				{
					if (error != null)
					{
						error(obj2);
					}
				}
			};
			try
			{
				sourceStream.BeginRead(buff, 0, bufferLength, callback, null);
			}
			catch (Exception obj)
			{
				if (error != null)
				{
					error(obj);
				}
			}
		}

		internal static byte[] Decompress(this byte[] data, CompressionMethod method)
		{
			return (method == CompressionMethod.Deflate) ? data.decompress() : data;
		}

		internal static Stream Decompress(this Stream stream, CompressionMethod method)
		{
			return (method == CompressionMethod.Deflate) ? stream.decompress() : stream;
		}

		internal static byte[] DecompressToArray(this Stream stream, CompressionMethod method)
		{
			return (method == CompressionMethod.Deflate) ? stream.decompressToArray() : stream.ToByteArray();
		}

		internal static void Emit(this EventHandler eventHandler, object sender, EventArgs e)
		{
			eventHandler?.Invoke(sender, e);
		}

		internal static void Emit<TEventArgs>(this EventHandler<TEventArgs> eventHandler, object sender, TEventArgs e) where TEventArgs : EventArgs
		{
			eventHandler?.Invoke(sender, e);
		}

		internal static string GetAbsolutePath(this Uri uri)
		{
			if (uri.IsAbsoluteUri)
			{
				return uri.AbsolutePath;
			}
			string originalString = uri.OriginalString;
			if (originalString[0] != '/')
			{
				return null;
			}
			int num = originalString.IndexOfAny(new char[2] { '?', '#' });
			return (num > 0) ? originalString.Substring(0, num) : originalString;
		}

		internal static WebSocketSharp.Net.CookieCollection GetCookies(this NameValueCollection headers, bool response)
		{
			string text = headers[response ? "Set-Cookie" : "Cookie"];
			return (text != null) ? WebSocketSharp.Net.CookieCollection.Parse(text, response) : new WebSocketSharp.Net.CookieCollection();
		}

		internal static string GetDnsSafeHost(this Uri uri, bool bracketIPv6)
		{
			return (bracketIPv6 && uri.HostNameType == UriHostNameType.IPv6) ? uri.Host : uri.DnsSafeHost;
		}

		internal static string GetMessage(this CloseStatusCode code)
		{
			return code switch
			{
				CloseStatusCode.ProtocolError => "A protocol error has occurred.", 
				CloseStatusCode.UnsupportedData => "Unsupported data has been received.", 
				CloseStatusCode.Abnormal => "An abnormal error has occurred.", 
				CloseStatusCode.InvalidData => "Invalid data has been received.", 
				CloseStatusCode.PolicyViolation => "A policy violation has occurred.", 
				CloseStatusCode.TooBig => "A too big message has been received.", 
				CloseStatusCode.MandatoryExtension => "The client did not receive expected extension(s).", 
				CloseStatusCode.ServerError => "The server got an internal error.", 
				CloseStatusCode.TlsHandshakeFailure => "An error has occurred during a TLS handshake.", 
				_ => string.Empty, 
			};
		}

		internal static string GetName(this string nameAndValue, char separator)
		{
			int num = nameAndValue.IndexOf(separator);
			return (num > 0) ? nameAndValue.Substring(0, num).Trim() : null;
		}

		internal static string GetUTF8DecodedString(this byte[] bytes)
		{
			return Encoding.UTF8.GetString(bytes);
		}

		internal static byte[] GetUTF8EncodedBytes(this string s)
		{
			return Encoding.UTF8.GetBytes(s);
		}

		internal static string GetValue(this string nameAndValue, char separator)
		{
			return nameAndValue.GetValue(separator, unquote: false);
		}

		internal static string GetValue(this string nameAndValue, char separator, bool unquote)
		{
			int num = nameAndValue.IndexOf(separator);
			if (num < 0 || num == nameAndValue.Length - 1)
			{
				return null;
			}
			string text = nameAndValue.Substring(num + 1).Trim();
			return unquote ? text.Unquote() : text;
		}

		internal static bool IsCompressionExtension(this string value, CompressionMethod method)
		{
			string value2 = method.ToExtensionString();
			StringComparison comparisonType = StringComparison.Ordinal;
			return value.StartsWith(value2, comparisonType);
		}

		internal static bool IsControl(this byte opcode)
		{
			return opcode > 7 && opcode < 16;
		}

		internal static bool IsControl(this Opcode opcode)
		{
			return (int)opcode >= 8;
		}

		internal static bool IsData(this byte opcode)
		{
			return opcode == 1 || opcode == 2;
		}

		internal static bool IsData(this Opcode opcode)
		{
			return opcode == Opcode.Text || opcode == Opcode.Binary;
		}

		internal static bool IsEqualTo(this int value, char c, Action<int> beforeComparing)
		{
			beforeComparing(value);
			return value == c;
		}

		internal static bool IsHttpMethod(this string value)
		{
			int result;
			switch (value)
			{
			default:
				result = ((value == "TRACE") ? 1 : 0);
				break;
			case "GET":
			case "HEAD":
			case "POST":
			case "PUT":
			case "DELETE":
			case "CONNECT":
			case "OPTIONS":
				result = 1;
				break;
			}
			return (byte)result != 0;
		}

		internal static bool IsPortNumber(this int value)
		{
			return value > 0 && value < 65536;
		}

		internal static bool IsReserved(this ushort code)
		{
			return code == 1004 || code == 1005 || code == 1006 || code == 1015;
		}

		internal static bool IsReserved(this CloseStatusCode code)
		{
			return code == CloseStatusCode.Undefined || code == CloseStatusCode.NoStatus || code == CloseStatusCode.Abnormal || code == CloseStatusCode.TlsHandshakeFailure;
		}

		internal static bool IsSupported(this byte opcode)
		{
			return Enum.IsDefined(typeof(Opcode), opcode);
		}

		internal static bool IsText(this string value)
		{
			int length = value.Length;
			for (int i = 0; i < length; i++)
			{
				char c = value[i];
				if (c < ' ')
				{
					if ("\r\n\t".IndexOf(c) == -1)
					{
						return false;
					}
					if (c == '\n')
					{
						i++;
						if (i == length)
						{
							break;
						}
						c = value[i];
						if (" \t".IndexOf(c) == -1)
						{
							return false;
						}
					}
				}
				else if (c == '\u007f')
				{
					return false;
				}
			}
			return true;
		}

		internal static bool IsToken(this string value)
		{
			foreach (char c in value)
			{
				if (c < ' ')
				{
					return false;
				}
				if (c > '~')
				{
					return false;
				}
				if ("()<>@,;:\\\"/[]?={} \t".IndexOf(c) > -1)
				{
					return false;
				}
			}
			return true;
		}

		internal static bool KeepsAlive(this NameValueCollection headers, Version version)
		{
			StringComparison comparisonTypeForValue = StringComparison.OrdinalIgnoreCase;
			return (version < WebSocketSharp.Net.HttpVersion.Version11) ? headers.Contains("Connection", "keep-alive", comparisonTypeForValue) : (!headers.Contains("Connection", "close", comparisonTypeForValue));
		}

		internal static bool MaybeUri(this string value)
		{
			int num = value.IndexOf(':');
			if (num < 2 || num > 9)
			{
				return false;
			}
			string value2 = value.Substring(0, num);
			return value2.isPredefinedScheme();
		}

		internal static string Quote(this string value)
		{
			string format = "\"{0}\"";
			string arg = value.Replace("\"", "\\\"");
			return string.Format(format, arg);
		}

		internal static byte[] ReadBytes(this Stream stream, int length)
		{
			byte[] array = new byte[length];
			int num = 0;
			int num2 = 0;
			while (length > 0)
			{
				int num3 = stream.Read(array, num, length);
				if (num3 <= 0)
				{
					if (num2 >= _maxRetry)
					{
						return array.SubArray(0, num);
					}
					num2++;
				}
				else
				{
					num2 = 0;
					num += num3;
					length -= num3;
				}
			}
			return array;
		}

		internal static byte[] ReadBytes(this Stream stream, long length, int bufferLength)
		{
			using MemoryStream memoryStream = new MemoryStream();
			byte[] buffer = new byte[bufferLength];
			int num = 0;
			while (length > 0)
			{
				if (length < bufferLength)
				{
					bufferLength = (int)length;
				}
				int num2 = stream.Read(buffer, 0, bufferLength);
				if (num2 <= 0)
				{
					if (num >= _maxRetry)
					{
						break;
					}
					num++;
				}
				else
				{
					num = 0;
					memoryStream.Write(buffer, 0, num2);
					length -= num2;
				}
			}
			memoryStream.Close();
			return memoryStream.ToArray();
		}

		internal static void ReadBytesAsync(this Stream stream, int length, Action<byte[]> completed, Action<Exception> error)
		{
			byte[] ret = new byte[length];
			int offset = 0;
			int retry = 0;
			AsyncCallback callback = null;
			callback = delegate(IAsyncResult ar)
			{
				try
				{
					int num = stream.EndRead(ar);
					if (num <= 0)
					{
						if (retry < _maxRetry)
						{
							retry++;
							stream.BeginRead(ret, offset, length, callback, null);
						}
						else if (completed != null)
						{
							completed(ret.SubArray(0, offset));
						}
					}
					else if (num == length)
					{
						if (completed != null)
						{
							completed(ret);
						}
					}
					else
					{
						retry = 0;
						offset += num;
						length -= num;
						stream.BeginRead(ret, offset, length, callback, null);
					}
				}
				catch (Exception obj2)
				{
					if (error != null)
					{
						error(obj2);
					}
				}
			};
			try
			{
				stream.BeginRead(ret, offset, length, callback, null);
			}
			catch (Exception obj)
			{
				if (error != null)
				{
					error(obj);
				}
			}
		}

		internal static void ReadBytesAsync(this Stream stream, long length, int bufferLength, Action<byte[]> completed, Action<Exception> error)
		{
			MemoryStream dest = new MemoryStream();
			byte[] buff = new byte[bufferLength];
			int retry = 0;
			Action<long> read = null;
			read = delegate(long len)
			{
				if (len < bufferLength)
				{
					bufferLength = (int)len;
				}
				stream.BeginRead(buff, 0, bufferLength, delegate(IAsyncResult ar)
				{
					try
					{
						int num = stream.EndRead(ar);
						if (num <= 0)
						{
							if (retry < _maxRetry)
							{
								int num2 = retry;
								retry = num2 + 1;
								read(len);
							}
							else
							{
								if (completed != null)
								{
									dest.Close();
									byte[] obj2 = dest.ToArray();
									completed(obj2);
								}
								dest.Dispose();
							}
						}
						else
						{
							dest.Write(buff, 0, num);
							if (num == len)
							{
								if (completed != null)
								{
									dest.Close();
									byte[] obj3 = dest.ToArray();
									completed(obj3);
								}
								dest.Dispose();
							}
							else
							{
								retry = 0;
								read(len - num);
							}
						}
					}
					catch (Exception obj4)
					{
						dest.Dispose();
						if (error != null)
						{
							error(obj4);
						}
					}
				}, null);
			};
			try
			{
				read(length);
			}
			catch (Exception obj)
			{
				dest.Dispose();
				if (error != null)
				{
					error(obj);
				}
			}
		}

		internal static T[] Reverse<T>(this T[] array)
		{
			long num = array.LongLength;
			T[] array2 = new T[num];
			long num2 = num - 1;
			for (long num3 = 0L; num3 <= num2; num3++)
			{
				array2[num3] = array[num2 - num3];
			}
			return array2;
		}

		internal static IEnumerable<string> SplitHeaderValue(this string value, params char[] separators)
		{
			int len = value.Length;
			int end = len - 1;
			StringBuilder buff = new StringBuilder(32);
			bool escaped = false;
			bool quoted = false;
			for (int i = 0; i <= end; i++)
			{
				char c = value[i];
				buff.Append(c);
				switch (c)
				{
				case '"':
					if (escaped)
					{
						escaped = false;
					}
					else
					{
						quoted = !quoted;
					}
					continue;
				case '\\':
					if (i == end)
					{
						break;
					}
					if (value[i + 1] == '"')
					{
						escaped = true;
					}
					continue;
				default:
					if (Array.IndexOf(separators, c) > -1 && !quoted)
					{
						buff.Length--;
						yield return buff.ToString();
						buff.Length = 0;
					}
					continue;
				}
				break;
			}
			yield return buff.ToString();
		}

		internal static byte[] ToByteArray(this Stream stream)
		{
			stream.Position = 0L;
			using MemoryStream memoryStream = new MemoryStream();
			CopyTo(stream, memoryStream, 1024);
			memoryStream.Close();
			return memoryStream.ToArray();
		}

		internal static byte[] ToByteArray(this ushort value, ByteOrder order)
		{
			byte[] bytes = BitConverter.GetBytes(value);
			if (!order.IsHostOrder())
			{
				Array.Reverse((Array)bytes);
			}
			return bytes;
		}

		internal static byte[] ToByteArray(this ulong value, ByteOrder order)
		{
			byte[] bytes = BitConverter.GetBytes(value);
			if (!order.IsHostOrder())
			{
				Array.Reverse((Array)bytes);
			}
			return bytes;
		}

		internal static CompressionMethod ToCompressionMethod(this string value)
		{
			Array values = Enum.GetValues(typeof(CompressionMethod));
			foreach (CompressionMethod item in values)
			{
				if (item.ToExtensionString() == value)
				{
					return item;
				}
			}
			return CompressionMethod.None;
		}

		internal static string ToExtensionString(this CompressionMethod method, params string[] parameters)
		{
			if (method == CompressionMethod.None)
			{
				return string.Empty;
			}
			string arg = method.ToString().ToLower();
			string text = $"permessage-{arg}";
			if (parameters == null || parameters.Length == 0)
			{
				return text;
			}
			string arg2 = parameters.ToString("; ");
			return $"{text}; {arg2}";
		}

		internal static IPAddress ToIPAddress(this string value)
		{
			if (value == null || value.Length == 0)
			{
				return null;
			}
			if (IPAddress.TryParse(value, out IPAddress address))
			{
				return address;
			}
			try
			{
				IPAddress[] hostAddresses = Dns.GetHostAddresses(value);
				return hostAddresses[0];
			}
			catch
			{
				return null;
			}
		}

		internal static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
		{
			return new List<TSource>(source);
		}

		internal static string ToString(this IPAddress address, bool bracketIPv6)
		{
			return (bracketIPv6 && address.AddressFamily == AddressFamily.InterNetworkV6) ? $"[{address}]" : address.ToString();
		}

		internal static ushort ToUInt16(this byte[] source, ByteOrder sourceOrder)
		{
			byte[] value = source.ToHostOrder(sourceOrder);
			return BitConverter.ToUInt16(value, 0);
		}

		internal static ulong ToUInt64(this byte[] source, ByteOrder sourceOrder)
		{
			byte[] value = source.ToHostOrder(sourceOrder);
			return BitConverter.ToUInt64(value, 0);
		}

		internal static IEnumerable<string> TrimEach(this IEnumerable<string> source)
		{
			foreach (string elm in source)
			{
				yield return elm.Trim();
			}
		}

		internal static string TrimSlashFromEnd(this string value)
		{
			string text = value.TrimEnd(new char[1] { '/' });
			return (text.Length > 0) ? text : "/";
		}

		internal static string TrimSlashOrBackslashFromEnd(this string value)
		{
			string text = value.TrimEnd('/', '\\');
			return (text.Length > 0) ? text : value[0].ToString();
		}

		internal static bool TryCreateVersion(this string versionString, out Version result)
		{
			result = null;
			try
			{
				result = new Version(versionString);
			}
			catch
			{
				return false;
			}
			return true;
		}

		internal static bool TryCreateWebSocketUri(this string uriString, out Uri result, out string message)
		{
			result = null;
			message = null;
			Uri uri = uriString.ToUri();
			if (uri == null)
			{
				message = "An invalid URI string.";
				return false;
			}
			if (!uri.IsAbsoluteUri)
			{
				message = "A relative URI.";
				return false;
			}
			string scheme = uri.Scheme;
			if (!(scheme == "ws") && !(scheme == "wss"))
			{
				message = "The scheme part is not 'ws' or 'wss'.";
				return false;
			}
			int port = uri.Port;
			if (port == 0)
			{
				message = "The port part is zero.";
				return false;
			}
			if (uri.Fragment.Length > 0)
			{
				message = "It includes the fragment component.";
				return false;
			}
			if (port == -1)
			{
				port = ((scheme == "ws") ? 80 : 443);
				uriString = $"{scheme}://{uri.Host}:{port}{uri.PathAndQuery}";
				result = new Uri(uriString);
			}
			else
			{
				result = uri;
			}
			return true;
		}

		internal static bool TryGetUTF8DecodedString(this byte[] bytes, out string s)
		{
			s = null;
			try
			{
				s = Encoding.UTF8.GetString(bytes);
			}
			catch
			{
				return false;
			}
			return true;
		}

		internal static bool TryGetUTF8EncodedBytes(this string s, out byte[] bytes)
		{
			bytes = null;
			try
			{
				bytes = Encoding.UTF8.GetBytes(s);
			}
			catch
			{
				return false;
			}
			return true;
		}

		internal static bool TryOpenRead(this FileInfo fileInfo, out FileStream fileStream)
		{
			fileStream = null;
			try
			{
				fileStream = fileInfo.OpenRead();
			}
			catch
			{
				return false;
			}
			return true;
		}

		internal static string Unquote(this string value)
		{
			int num = value.IndexOf('"');
			if (num == -1)
			{
				return value;
			}
			int num2 = value.LastIndexOf('"');
			if (num2 == num)
			{
				return value;
			}
			int num3 = num2 - num - 1;
			return (num3 > 0) ? value.Substring(num + 1, num3).Replace("\\\"", "\"") : string.Empty;
		}

		internal static bool Upgrades(this NameValueCollection headers, string protocol)
		{
			StringComparison comparisonTypeForValue = StringComparison.OrdinalIgnoreCase;
			return headers.Contains("Upgrade", protocol, comparisonTypeForValue) && headers.Contains("Connection", "Upgrade", comparisonTypeForValue);
		}

		internal static string UrlDecode(this string value, Encoding encoding)
		{
			return (value.IndexOfAny(new char[2] { '%', '+' }) > -1) ? HttpUtility.UrlDecode(value, encoding) : value;
		}

		internal static string UrlEncode(this string value, Encoding encoding)
		{
			return HttpUtility.UrlEncode(value, encoding);
		}

		internal static void WriteBytes(this Stream stream, byte[] bytes, int bufferLength)
		{
			using MemoryStream sourceStream = new MemoryStream(bytes);
			CopyTo(sourceStream, stream, bufferLength);
		}

		internal static void WriteBytesAsync(this Stream stream, byte[] bytes, int bufferLength, Action completed, Action<Exception> error)
		{
			MemoryStream src = new MemoryStream(bytes);
			src.CopyToAsync(stream, bufferLength, delegate
			{
				if (completed != null)
				{
					completed();
				}
				src.Dispose();
			}, delegate(Exception ex)
			{
				src.Dispose();
				if (error != null)
				{
					error(ex);
				}
			});
		}

		public static string GetDescription(this WebSocketSharp.Net.HttpStatusCode code)
		{
			return ((int)code).GetStatusDescription();
		}

		public static string GetStatusDescription(this int code)
		{
			return code switch
			{
				100 => "Continue", 
				101 => "Switching Protocols", 
				102 => "Processing", 
				200 => "OK", 
				201 => "Created", 
				202 => "Accepted", 
				203 => "Non-Authoritative Information", 
				204 => "No Content", 
				205 => "Reset Content", 
				206 => "Partial Content", 
				207 => "Multi-Status", 
				300 => "Multiple Choices", 
				301 => "Moved Permanently", 
				302 => "Found", 
				303 => "See Other", 
				304 => "Not Modified", 
				305 => "Use Proxy", 
				307 => "Temporary Redirect", 
				400 => "Bad Request", 
				401 => "Unauthorized", 
				402 => "Payment Required", 
				403 => "Forbidden", 
				404 => "Not Found", 
				405 => "Method Not Allowed", 
				406 => "Not Acceptable", 
				407 => "Proxy Authentication Required", 
				408 => "Request Timeout", 
				409 => "Conflict", 
				410 => "Gone", 
				411 => "Length Required", 
				412 => "Precondition Failed", 
				413 => "Request Entity Too Large", 
				414 => "Request-Uri Too Long", 
				415 => "Unsupported Media Type", 
				416 => "Requested Range Not Satisfiable", 
				417 => "Expectation Failed", 
				422 => "Unprocessable Entity", 
				423 => "Locked", 
				424 => "Failed Dependency", 
				500 => "Internal Server Error", 
				501 => "Not Implemented", 
				502 => "Bad Gateway", 
				503 => "Service Unavailable", 
				504 => "Gateway Timeout", 
				505 => "Http Version Not Supported", 
				507 => "Insufficient Storage", 
				_ => string.Empty, 
			};
		}

		public static bool IsCloseStatusCode(this ushort value)
		{
			return value > 999 && value < 5000;
		}

		public static bool IsEnclosedIn(this string value, char c)
		{
			if (value == null)
			{
				return false;
			}
			int length = value.Length;
			return length > 1 && value[0] == c && value[length - 1] == c;
		}

		public static bool IsHostOrder(this ByteOrder order)
		{
			return BitConverter.IsLittleEndian == (order == ByteOrder.Little);
		}

		public static bool IsLocal(this IPAddress address)
		{
			if (address == null)
			{
				throw new ArgumentNullException("address");
			}
			if (address.Equals(IPAddress.Any))
			{
				return true;
			}
			if (address.Equals(IPAddress.Loopback))
			{
				return true;
			}
			if (Socket.OSSupportsIPv6)
			{
				if (address.Equals(IPAddress.IPv6Any))
				{
					return true;
				}
				if (address.Equals(IPAddress.IPv6Loopback))
				{
					return true;
				}
			}
			string hostName = Dns.GetHostName();
			IPAddress[] hostAddresses = Dns.GetHostAddresses(hostName);
			IPAddress[] array = hostAddresses;
			foreach (IPAddress obj in array)
			{
				if (address.Equals(obj))
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsNullOrEmpty(this string value)
		{
			return value == null || value.Length == 0;
		}

		public static T[] SubArray<T>(this T[] array, int startIndex, int length)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			int num = array.Length;
			if (num == 0)
			{
				if (startIndex != 0)
				{
					throw new ArgumentOutOfRangeException("startIndex");
				}
				if (length != 0)
				{
					throw new ArgumentOutOfRangeException("length");
				}
				return array;
			}
			if (startIndex < 0 || startIndex >= num)
			{
				throw new ArgumentOutOfRangeException("startIndex");
			}
			if (length < 0 || length > num - startIndex)
			{
				throw new ArgumentOutOfRangeException("length");
			}
			if (length == 0)
			{
				return new T[0];
			}
			if (length == num)
			{
				return array;
			}
			T[] array2 = new T[length];
			Array.Copy(array, startIndex, array2, 0, length);
			return array2;
		}

		public static T[] SubArray<T>(this T[] array, long startIndex, long length)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			long num = array.LongLength;
			if (num == 0)
			{
				if (startIndex != 0)
				{
					throw new ArgumentOutOfRangeException("startIndex");
				}
				if (length != 0)
				{
					throw new ArgumentOutOfRangeException("length");
				}
				return array;
			}
			if (startIndex < 0 || startIndex >= num)
			{
				throw new ArgumentOutOfRangeException("startIndex");
			}
			if (length < 0 || length > num - startIndex)
			{
				throw new ArgumentOutOfRangeException("length");
			}
			if (length == 0)
			{
				return new T[0];
			}
			if (length == num)
			{
				return array;
			}
			T[] array2 = new T[length];
			Array.Copy(array, startIndex, array2, 0L, length);
			return array2;
		}

		public static void Times(this int n, Action<int> action)
		{
			if (n > 0 && action != null)
			{
				for (int i = 0; i < n; i++)
				{
					action(i);
				}
			}
		}

		public static void Times(this long n, Action<long> action)
		{
			if (n > 0 && action != null)
			{
				for (long num = 0L; num < n; num++)
				{
					action(num);
				}
			}
		}

		public static byte[] ToHostOrder(this byte[] source, ByteOrder sourceOrder)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (source.Length < 2)
			{
				return source;
			}
			if (sourceOrder.IsHostOrder())
			{
				return source;
			}
			return source.Reverse();
		}

		public static string ToString<T>(this T[] array, string separator)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			int num = array.Length;
			if (num == 0)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder(64);
			int num2 = num - 1;
			for (int i = 0; i < num2; i++)
			{
				stringBuilder.AppendFormat("{0}{1}", array[i], separator);
			}
			stringBuilder.AppendFormat("{0}", array[num2]);
			return stringBuilder.ToString();
		}

		public static Uri ToUri(this string value)
		{
			if (value == null || value.Length == 0)
			{
				return null;
			}
			UriKind uriKind = (value.MaybeUri() ? UriKind.Absolute : UriKind.Relative);
			Uri.TryCreate(value, uriKind, out Uri result);
			return result;
		}
	}
	public class MessageEventArgs : EventArgs
	{
		private string _data;

		private bool _dataSet;

		private Opcode _opcode;

		private byte[] _rawData;

		internal Opcode Opcode => _opcode;

		public string Data
		{
			get
			{
				setData();
				return _data;
			}
		}

		public bool IsBinary => _opcode == Opcode.Binary;

		public bool IsPing => _opcode == Opcode.Ping;

		public bool IsText => _opcode == Opcode.Text;

		public byte[] RawData
		{
			get
			{
				setData();
				return _rawData;
			}
		}

		internal MessageEventArgs(WebSocketFrame frame)
		{
			_opcode = frame.Opcode;
			_rawData = frame.PayloadData.ApplicationData;
		}

		internal MessageEventArgs(Opcode opcode, byte[] rawData)
		{
			if ((ulong)rawData.LongLength > PayloadData.MaxLength)
			{
				throw new WebSocketException(CloseStatusCode.TooBig);
			}
			_opcode = opcode;
			_rawData = rawData;
		}

		private void setData()
		{
			if (_dataSet)
			{
				return;
			}
			if (_opcode == Opcode.Binary)
			{
				_dataSet = true;
				return;
			}
			if (_rawData.TryGetUTF8DecodedString(out var s))
			{
				_data = s;
			}
			_dataSet = true;
		}
	}
	public class CloseEventArgs : EventArgs
	{
		private bool _clean;

		private PayloadData _payloadData;

		public ushort Code => _payloadData.Code;

		public string Reason => _payloadData.Reason;

		public bool WasClean => _clean;

		internal CloseEventArgs(PayloadData payloadData, bool clean)
		{
			_payloadData = payloadData;
			_clean = clean;
		}

		internal CloseEventArgs(ushort code, string reason, bool clean)
		{
			_payloadData = new PayloadData(code, reason);
			_clean = clean;
		}
	}
	public enum ByteOrder
	{
		Little,
		Big
	}
	public class ErrorEventArgs : EventArgs
	{
		private Exception _exception;

		private string _message;

		public Exception Exception => _exception;

		public string Message => _message;

		internal ErrorEventArgs(string message)
			: this(message, null)
		{
		}

		internal ErrorEventArgs(string message, Exception exception)
		{
			_message = message;
			_exception = exception;
		}
	}
	public class WebSocket : IDisposable
	{
		private AuthenticationChallenge _authChallenge;

		private string _base64Key;

		private bool _client;

		private Action _closeContext;

		private CompressionMethod _compression;

		private WebSocketContext _context;

		private WebSocketSharp.Net.CookieCollection _cookies;

		private WebSocketSharp.Net.NetworkCredential _credentials;

		private bool _emitOnPing;

		private bool _enableRedirection;

		private string _extensions;

		private bool _extensionsRequested;

		private object _forMessageEventQueue;

		private object _forPing;

		private object _forSend;

		private object _forState;

		private MemoryStream _fragmentsBuffer;

		private bool _fragmentsCompressed;

		private Opcode _fragmentsOpcode;

		private const string _guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

		private Func<WebSocketContext, string> _handshakeRequestChecker;

		private bool _ignoreExtensions;

		private bool _inContinuation;

		private volatile bool _inMessage;

		private volatile Logger _logger;

		private static readonly int _maxRetryCountForConnect;

		private Action<MessageEventArgs> _message;

		private Queue<MessageEventArgs> _messageEventQueue;

		private uint _nonceCount;

		private string _origin;

		private ManualResetEvent _pongReceived;

		private bool _preAuth;

		private string _protocol;

		private string[] _protocols;

		private bool _protocolsRequested;

		private WebSocketSharp.Net.NetworkCredential _proxyCredentials;

		private Uri _proxyUri;

		private volatile WebSocketState _readyState;

		private ManualResetEvent _receivingExited;

		private int _retryCountForConnect;

		private bool _secure;

		private ClientSslConfiguration _sslConfig;

		private Stream _stream;

		private TcpClient _tcpClient;

		private Uri _uri;

		private const string _version = "13";

		private TimeSpan _waitTime;

		internal static readonly byte[] EmptyBytes;

		internal static readonly int FragmentLength;

		internal static readonly RandomNumberGenerator RandomNumber;

		internal WebSocketSharp.Net.CookieCollection CookieCollection => _cookies;

		internal Func<WebSocketContext, string> CustomHandshakeRequestChecker
		{
			get
			{
				return _handshakeRequestChecker;
			}
			set
			{
				_handshakeRequestChecker = value;
			}
		}

		internal bool HasMessage
		{
			get
			{
				lock (_forMessageEventQueue)
				{
					return _messageEventQueue.Count > 0;
				}
			}
		}

		internal bool IgnoreExtensions
		{
			get
			{
				return _ignoreExtensions;
			}
			set
			{
				_ignoreExtensions = value;
			}
		}

		internal bool IsConnected => _readyState == WebSocketState.Open || _readyState == WebSocketState.Closing;

		public CompressionMethod Compression
		{
			get
			{
				return _compression;
			}
			set
			{
				string text = null;
				if (!_client)
				{
					text = "This instance is not a client.";
					throw new InvalidOperationException(text);
				}
				if (!canSet(out text))
				{
					_logger.Warn(text);
					return;
				}
				lock (_forState)
				{
					if (!canSet(out text))
					{
						_logger.Warn(text);
					}
					else
					{
						_compression = value;
					}
				}
			}
		}

		public IEnumerable<WebSocketSharp.Net.Cookie> Cookies
		{
			get
			{
				lock (_cookies.SyncRoot)
				{
					foreach (WebSocketSharp.Net.Cookie cookie in _cookies)
					{
						yield return cookie;
					}
				}
			}
		}

		public WebSocketSharp.Net.NetworkCredential Credentials => _credentials;

		public bool EmitOnPing
		{
			get
			{
				return _emitOnPing;
			}
			set
			{
				_emitOnPing = value;
			}
		}

		public bool EnableRedirection
		{
			get
			{
				return _enableRedirection;
			}
			set
			{
				string text = null;
				if (!_client)
				{
					text = "This instance is not a client.";
					throw new InvalidOperationException(text);
				}
				if (!canSet(out text))
				{
					_logger.Warn(text);
					return;
				}
				lock (_forState)
				{
					if (!canSet(out text))
					{
						_logger.Warn(text);
					}
					else
					{
						_enableRedirection = value;
					}
				}
			}
		}

		public string Extensions => _extensions ?? string.Empty;

		public bool IsAlive => ping(EmptyBytes);

		public bool IsSecure => _secure;

		public Logger Log
		{
			get
			{
				return _logger;
			}
			internal set
			{
				_logger = value;
			}
		}

		public string Origin
		{
			get
			{
				return _origin;
			}
			set
			{
				string text = null;
				if (!_client)
				{
					text = "This instance is not a client.";
					throw new InvalidOperationException(text);
				}
				if (!value.IsNullOrEmpty())
				{
					if (!Uri.TryCreate(value, UriKind.Absolute, out Uri result))
					{
						text = "Not an absolute URI string.";
						throw new ArgumentException(text, "value");
					}
					if (result.Segments.Length > 1)
					{
						text = "It includes the path segments.";
						throw new ArgumentException(text, "value");
					}
				}
				if (!canSet(out text))
				{
					_logger.Warn(text);
					return;
				}
				lock (_forState)
				{
					if (!canSet(out text))
					{
						_logger.Warn(text);
						return;
					}
					_origin = ((!value.IsNullOrEmpty()) ? value.TrimEnd(new char[1] { '/' }) : value);
				}
			}
		}

		public string Protocol
		{
			get
			{
				return _protocol ?? string.Empty;
			}
			internal set
			{
				_protocol = value;
			}
		}

		public WebSocketState ReadyState => _readyState;

		public ClientSslConfiguration SslConfiguration
		{
			get
			{
				if (!_client)
				{
					string text = "This instance is not a client.";
					throw new InvalidOperationException(text);
				}
				if (!_secure)
				{
					string text2 = "This instance does not use a secure connection.";
					throw new InvalidOperationException(text2);
				}
				return getSslConfiguration();
			}
		}

		public Uri Url => _client ? _uri : _context.RequestUri;

		public TimeSpan WaitTime
		{
			get
			{
				return _waitTime;
			}
			set
			{
				if (value <= TimeSpan.Zero)
				{
					throw new ArgumentOutOfRangeException("value", "Zero or less.");
				}
				if (!canSet(out var text))
				{
					_logger.Warn(text);
					return;
				}
				lock (_forState)
				{
					if (!canSet(out text))
					{
						_logger.Warn(text);
					}
					else
					{
						_waitTime = value;
					}
				}
			}
		}

		public event EventHandler<CloseEventArgs> OnClose;

		public event EventHandler<ErrorEventArgs> OnError;

		public event EventHandler<MessageEventArgs> OnMessage;

		public event EventHandler OnOpen;

		static WebSocket()
		{
			_maxRetryCountForConnect = 10;
			EmptyBytes = new byte[0];
			FragmentLength = 128000;
			RandomNumber = new RNGCryptoServiceProvider();
		}

		internal WebSocket(HttpListenerWebSocketContext context, string protocol)
		{
			_context = context;
			_protocol = protocol;
			_closeContext = context.Close;
			_logger = context.Log;
			_message = messages;
			_secure = context.IsSecureConnection;
			_stream = context.Stream;
			_waitTime = TimeSpan.FromSeconds(1.0);
			init();
		}

		internal WebSocket(TcpListenerWebSocketContext context, string protocol)
		{
			_context = context;
			_protocol = protocol;
			_closeContext = context.Close;
			_logger = context.Log;
			_message = messages;
			_secure = context.IsSecureConnection;
			_stream = context.Stream;
			_waitTime = TimeSpan.FromSeconds(1.0);
			init();
		}

		public WebSocket(string url, params string[] protocols)
		{
			if (url == null)
			{
				throw new ArgumentNullException("url");
			}
			if (url.Length == 0)
			{
				throw new ArgumentException("An empty string.", "url");
			}
			if (!url.TryCreateWebSocketUri(out _uri, out var text))
			{
				throw new ArgumentException(text, "url");
			}
			if (protocols != null && protocols.Length != 0)
			{
				if (!checkProtocols(protocols, out text))
				{
					throw new ArgumentException(text, "protocols");
				}
				_protocols = protocols;
			}
			_base64Key = CreateBase64Key();
			_client = true;
			_logger = new Logger();
			_message = messagec;
			_secure = _uri.Scheme == "wss";
			_waitTime = TimeSpan.FromSeconds(5.0);
			init();
		}

		private bool accept()
		{
			if (_readyState == WebSocketState.Open)
			{
				string text = "The handshake request has already been accepted.";
				_logger.Warn(text);
				return false;
			}
			lock (_forState)
			{
				if (_readyState == WebSocketState.Open)
				{
					string text2 = "The handshake request has already been accepted.";
					_logger.Warn(text2);
					return false;
				}
				if (_readyState == WebSocketState.Closing)
				{
					string text3 = "The close process has set in.";
					_logger.Error(text3);
					text3 = "An interruption has occurred while attempting to accept.";
					error(text3, null);
					return false;
				}
				if (_readyState == WebSocketState.Closed)
				{
					string text4 = "The connection has been closed.";
					_logger.Error(text4);
					text4 = "An interruption has occurred while attempting to accept.";
					error(text4, null);
					return false;
				}
				try
				{
					if (!acceptHandshake())
					{
						return false;
					}
				}
				catch (Exception ex)
				{
					_logger.Fatal(ex.Message);
					_logger.Debug(ex.ToString());
					string text5 = "An exception has occurred while attempting to accept.";
					fatal(text5, ex);
					return false;
				}
				_readyState = WebSocketState.Open;
				return true;
			}
		}

		private bool acceptHandshake()
		{
			_logger.Debug($"A handshake request from {_context.UserEndPoint}:\n{_context}");
			if (!checkHandshakeRequest(_context, out var text))
			{
				_logger.Error(text);
				refuseHandshake(CloseStatusCode.ProtocolError, "A handshake error has occurred while attempting to accept.");
				return false;
			}
			if (!customCheckHandshakeRequest(_context, out text))
			{
				_logger.Error(text);
				refuseHandshake(CloseStatusCode.PolicyViolation, "A handshake error has occurred while attempting to accept.");
				return false;
			}
			_base64Key = _context.Headers["Sec-WebSocket-Key"];
			if (_protocol != null)
			{
				IEnumerable<string> secWebSocketProtocols = _context.SecWebSocketProtocols;
				processSecWebSocketProtocolClientHeader(secWebSocketProtocols);
			}
			if (!_ignoreExtensions)
			{
				string value = _context.Headers["Sec-WebSocket-Extensions"];
				processSecWebSocketExtensionsClientHeader(value);
			}
			return sendHttpResponse(createHandshakeResponse());
		}

		private bool canSet(out string message)
		{
			message = null;
			if (_readyState == WebSocketState.Open)
			{
				message = "The connection has already been established.";
				return false;
			}
			if (_readyState == WebSocketState.Closing)
			{
				message = "The connection is closing.";
				return false;
			}
			return true;
		}

		private bool checkHandshakeRequest(WebSocketContext context, out string message)
		{
			message = null;
			if (!context.IsWebSocketRequest)
			{
				message = "Not a handshake request.";
				return false;
			}
			if (context.RequestUri == null)
			{
				message = "It specifies an invalid Request-URI.";
				return false;
			}
			NameValueCollection headers = context.Headers;
			string text = headers["Sec-WebSocket-Key"];
			if (text == null)
			{
				message = "It includes no Sec-WebSocket-Key header.";
				return false;
			}
			if (text.Length == 0)
			{
				message = "It includes an invalid Sec-WebSocket-Key header.";
				return false;
			}
			string text2 = headers["Sec-WebSocket-Version"];
			if (text2 == null)
			{
				message = "It includes no Sec-WebSocket-Version header.";
				return false;
			}
			if (text2 != "13")
			{
				message = "It includes an invalid Sec-WebSocket-Version header.";
				return false;
			}
			string text3 = headers["Sec-WebSocket-Protocol"];
			if (text3 != null && text3.Length == 0)
			{
				message = "It includes an invalid Sec-WebSocket-Protocol header.";
				return false;
			}
			if (!_ignoreExtensions)
			{
				string text4 = headers["Sec-WebSocket-Extensions"];
				if (text4 != null && text4.Length == 0)
				{
					message = "It includes an invalid Sec-WebSocket-Extensions header.";
					return false;
				}
			}
			return true;
		}

		private bool checkHandshakeResponse(HttpResponse response, out string message)
		{
			message = null;
			if (response.IsRedirect)
			{
				message = "Indicates the redirection.";
				return false;
			}
			if (response.IsUnauthorized)
			{
				message = "Requires the authentication.";
				return false;
			}
			if (!response.IsWebSocketResponse)
			{
				message = "Not a WebSocket handshake response.";
				return false;
			}
			NameValueCollection headers = response.Headers;
			if (!validateSecWebSocketAcceptHeader(headers["Sec-WebSocket-Accept"]))
			{
				message = "Includes no Sec-WebSocket-Accept header, or it has an invalid value.";
				return false;
			}
			if (!validateSecWebSocketProtocolServerHeader(headers["Sec-WebSocket-Protocol"]))
			{
				message = "Includes no Sec-WebSocket-Protocol header, or it has an invalid value.";
				return false;
			}
			if (!validateSecWebSocketExtensionsServerHeader(headers["Sec-WebSocket-Extensions"]))
			{
				message = "Includes an invalid Sec-WebSocket-Extensions header.";
				return false;
			}
			if (!validateSecWebSocketVersionServerHeader(headers["Sec-WebSocket-Version"]))
			{
				message = "Includes an invalid Sec-WebSocket-Version header.";
				return false;
			}
			return true;
		}

		private static bool checkProtocols(string[] protocols, out string message)
		{
			message = null;
			Func<string, bool> condition = (string protocol) => protocol.IsNullOrEmpty() || !protocol.IsToken();
			if (protocols.Contains(condition))
			{
				message = "It contains a value that is not a token.";
				return false;
			}
			if (protocols.ContainsTwice())
			{
				message = "It contains a value twice.";
				return false;
			}
			return true;
		}

		private bool checkReceivedFrame(WebSocketFrame frame, out string message)
		{
			message = null;
			bool isMasked = frame.IsMasked;
			if (_client && isMasked)
			{
				message = "A frame from the server is masked.";
				return false;
			}
			if (!_client && !isMasked)
			{
				message = "A frame from a client is not masked.";
				return false;
			}
			if (_inContinuation && frame.IsData)
			{
				message = "A data frame has been received while receiving continuation frames.";
				return false;
			}
			if (frame.IsCompressed && _compression == CompressionMethod.None)
			{
				message = "A compressed frame has been received without any agreement for it.";
				return false;
			}
			if (frame.Rsv2 == Rsv.On)
			{
				message = "The RSV2 of a frame is non-zero without any negotiation for it.";
				return false;
			}
			if (frame.Rsv3 == Rsv.On)
			{
				message = "The RSV3 of a frame is non-zero without any negotiation for it.";
				return false;
			}
			return true;
		}

		private void close(ushort code, string reason)
		{
			if (_readyState == WebSocketState.Closing)
			{
				_logger.Info("The closing is already in progress.");
				return;
			}
			if (_readyState == WebSocketState.Closed)
			{
				_logger.Info("The connection has already been closed.");
				return;
			}
			if (code == 1005)
			{
				close(PayloadData.Empty, send: true, receive: true, received: false);
				return;
			}
			bool receive = !code.IsReserved();
			close(new PayloadData(code, reason), receive, receive, received: false);
		}

		private void close(PayloadData payloadData, bool send, bool receive, bool received)
		{
			lock (_forState)
			{
				if (_readyState == WebSocketState.Closing)
				{
					_logger.Info("The closing is already in progress.");
					return;
				}
				if (_readyState == WebSocketState.Closed)
				{
					_logger.Info("The connection has already been closed.");
					return;
				}
				send = send && _readyState == WebSocketState.Open;
				receive = send && receive;
				_readyState = WebSocketState.Closing;
			}
			_logger.Trace("Begin closing the connection.");
			bool clean = closeHandshake(payloadData, send, receive, received);
			releaseResources();
			_logger.Trace("End closing the connection.");
			_readyState = WebSocketState.Closed;
			CloseEventArgs e = new CloseEventArgs(payloadData, clean);
			try
			{
				this.OnClose.Emit(this, e);
			}
			catch (Exception ex)
			{
				_logger.Error(ex.Message);
				_logger.Debug(ex.ToString());
			}
		}

		private void closeAsync(ushort code, string reason)
		{
			if (_readyState == WebSocketState.Closing)
			{
				_logger.Info("The closing is already in progress.");
				return;
			}
			if (_readyState == WebSocketState.Closed)
			{
				_logger.Info("The connection has already been closed.");
				return;
			}
			if (code == 1005)
			{
				closeAsync(PayloadData.Empty, send: true, receive: true, received: false);
				return;
			}
			bool receive = !code.IsReserved();
			closeAsync(new PayloadData(code, reason), receive, receive, received: false);
		}

		private void closeAsync(PayloadData payloadData, bool send, bool receive, bool received)
		{
			Action<PayloadData, bool, bool, bool> closer = close;
			closer.BeginInvoke(payloadData, send, receive, received, delegate(IAsyncResult ar)
			{
				closer.EndInvoke(ar);
			}, null);
		}

		private bool closeHandshake(byte[] frameAsBytes, bool receive, bool received)
		{
			bool flag = frameAsBytes != null && sendBytes(frameAsBytes);
			if (!received && flag && receive && _receivingExited != null)
			{
				received = _receivingExited.WaitOne(_waitTime);
			}
			bool flag2 = flag && received;
			_logger.Debug($"Was clean?: {flag2}\n  sent: {flag}\n  received: {received}");
			return flag2;
		}

		private bool closeHandshake(PayloadData payloadData, bool send, bool receive, bool received)
		{
			bool flag = false;
			if (send)
			{
				WebSocketFrame webSocketFrame = WebSocketFrame.CreateCloseFrame(payloadData, _client);
				flag = sendBytes(webSocketFrame.ToArray());
				if (_client)
				{
					webSocketFrame.Unmask();
				}
			}
			if (!received && flag && receive && _receivingExited != null)
			{
				received = _receivingExited.WaitOne(_waitTime);
			}
			bool flag2 = flag && received;
			_logger.Debug($"Was clean?: {flag2}\n  sent: {flag}\n  received: {received}");
			return flag2;
		}

		private bool connect()
		{
			if (_readyState == WebSocketState.Open)
			{
				string text = "The connection has already been established.";
				_logger.Warn(text);
				return false;
			}
			lock (_forState)
			{
				if (_readyState == WebSocketState.Open)
				{
					string text2 = "The connection has already been established.";
					_logger.Warn(text2);
					return false;
				}
				if (_readyState == WebSocketState.Closing)
				{
					string text3 = "The close process has set in.";
					_logger.Error(text3);
					text3 = "An interruption has occurred while attempting to connect.";
					error(text3, null);
					return false;
				}
				if (_retryCountForConnect > _maxRetryCountForConnect)
				{
					string text4 = "An opportunity for reconnecting has been lost.";
					_logger.Error(text4);
					text4 = "An interruption has occurred while attempting to connect.";
					error(text4, null);
					return false;
				}
				_readyState = WebSocketState.Connecting;
				try
				{
					doHandshake();
				}
				catch (Exception ex)
				{
					_retryCountForConnect++;
					_logger.Fatal(ex.Message);
					_logger.Debug(ex.ToString());
					string text5 = "An exception has occurred while attempting to connect.";
					fatal(text5, ex);
					return false;
				}
				_retryCountForConnect = 1;
				_readyState = WebSocketState.Open;
				return true;
			}
		}

		private string createExtensions()
		{
			StringBuilder stringBuilder = new StringBuilder(80);
			if (_compression != 0)
			{
				string arg = _compression.ToExtensionString("server_no_context_takeover", "client_no_context_takeover");
				stringBuilder.AppendFormat("{0}, ", arg);
			}
			int length = stringBuilder.Length;
			if (length > 2)
			{
				stringBuilder.Length = length - 2;
				return stringBuilder.ToString();
			}
			return null;
		}

		private HttpResponse createHandshakeFailureResponse(WebSocketSharp.Net.HttpStatusCode code)
		{
			HttpResponse httpResponse = HttpResponse.CreateCloseResponse(code);
			httpResponse.Headers["Sec-WebSocket-Version"] = "13";
			return httpResponse;
		}

		private HttpRequest createHandshakeRequest()
		{
			HttpRequest httpRequest = HttpRequest.CreateWebSocketRequest(_uri);
			NameValueCollection headers = httpRequest.Headers;
			if (!_origin.IsNullOrEmpty())
			{
				headers["Origin"] = _origin;
			}
			headers["Sec-WebSocket-Key"] = _base64Key;
			_protocolsRequested = _protocols != null;
			if (_protocolsRequested)
			{
				headers["Sec-WebSocket-Protocol"] = _protocols.ToString(", ");
			}
			_extensionsRequested = _compression != CompressionMethod.None;
			if (_extensionsRequested)
			{
				headers["Sec-WebSocket-Extensions"] = createExtensions();
			}
			headers["Sec-WebSocket-Version"] = "13";
			AuthenticationResponse authenticationResponse = null;
			if (_authChallenge != null && _credentials != null)
			{
				authenticationResponse = new AuthenticationResponse(_authChallenge, _credentials, _nonceCount);
				_nonceCount = authenticationResponse.NonceCount;
			}
			else if (_preAuth)
			{
				authenticationResponse = new AuthenticationResponse(_credentials);
			}
			if (authenticationResponse != null)
			{
				headers["Authorization"] = authenticationResponse.ToString();
			}
			if (_cookies.Count > 0)
			{
				httpRequest.SetCookies(_cookies);
			}
			return httpRequest;
		}

		private HttpResponse createHandshakeResponse()
		{
			HttpResponse httpResponse = HttpResponse.CreateWebSocketResponse();
			NameValueCollection headers = httpResponse.Headers;
			headers["Sec-WebSocket-Accept"] = CreateResponseKey(_base64Key);
			if (_protocol != null)
			{
				headers["Sec-WebSocket-Protocol"] = _protocol;
			}
			if (_extensions != null)
			{
				headers["Sec-WebSocket-Extensions"] = _extensions;
			}
			if (_cookies.Count > 0)
			{
				httpResponse.SetCookies(_cookies);
			}
			return httpResponse;
		}

		private bool customCheckHandshakeRequest(WebSocketContext context, out string message)
		{
			message = null;
			if (_handshakeRequestChecker == null)
			{
				return true;
			}
			message = _handshakeRequestChecker(context);
			return message == null;
		}

		private MessageEventArgs dequeueFromMessageEventQueue()
		{
			lock (_forMessageEventQueue)
			{
				return (_messageEventQueue.Count > 0) ? _messageEventQueue.Dequeue() : null;
			}
		}

		private void doHandshake()
		{
			setClientStream();
			HttpResponse httpResponse = sendHandshakeRequest();
			if (!checkHandshakeResponse(httpResponse, out var text))
			{
				throw new WebSocketException(CloseStatusCode.ProtocolError, text);
			}
			if (_protocolsRequested)
			{
				_protocol = httpResponse.Headers["Sec-WebSocket-Protocol"];
			}
			if (_extensionsRequested)
			{
				processSecWebSocketExtensionsServerHeader(httpResponse.Headers["Sec-WebSocket-Extensions"]);
			}
			processCookies(httpResponse.Cookies);
		}

		private void enqueueToMessageEventQueue(MessageEventArgs e)
		{
			lock (_forMessageEventQueue)
			{
				_messageEventQueue.Enqueue(e);
			}
		}

		private void error(string message, Exception exception)
		{
			try
			{
				this.OnError.Emit(this, new ErrorEventArgs(message, exception));
			}
			catch (Exception ex)
			{
				_logger.Error(ex.Message);
				_logger.Debug(ex.ToString());
			}
		}

		private void fatal(string message, Exception exception)
		{
			CloseStatusCode code = ((exception is WebSocketException) ? ((WebSocketException)exception).Code : CloseStatusCode.Abnormal);
			fatal(message, (ushort)code);
		}

		private void fatal(string message, ushort code)
		{
			PayloadData payloadData = new PayloadData(code, message);
			close(payloadData, !code.IsReserved(), receive: false, received: false);
		}

		private void fatal(string message, CloseStatusCode code)
		{
			fatal(message, (ushort)code);
		}

		private ClientSslConfiguration getSslConfiguration()
		{
			if (_sslConfig == null)
			{
				_sslConfig = new ClientSslConfiguration(_uri.DnsSafeHost);
			}
			return _sslConfig;
		}

		private void init()
		{
			_compression = CompressionMethod.None;
			_cookies = new WebSocketSharp.Net.CookieCollection();
			_forPing = new object();
			_forSend = new object();
			_forState = new object();
			_messageEventQueue = new Queue<MessageEventArgs>();
			_forMessageEventQueue = ((ICollection)_messageEventQueue).SyncRoot;
			_readyState = WebSocketState.Connecting;
		}

		private void message()
		{
			MessageEventArgs obj = null;
			lock (_forMessageEventQueue)
			{
				if (_inMessage || _messageEventQueue.Count == 0 || _readyState != WebSocketState.Open)
				{
					return;
				}
				_inMessage = true;
				obj = _messageEventQueue.Dequeue();
			}
			_message(obj);
		}

		private void messagec(MessageEventArgs e)
		{
			while (true)
			{
				try
				{
					this.OnMessage.Emit(this, e);
				}
				catch (Exception ex)
				{
					_logger.Error(ex.ToString());
					error("An error has occurred during an OnMessage event.", ex);
				}
				lock (_forMessageEventQueue)
				{
					if (_messageEventQueue.Count == 0 || _readyState != WebSocketState.Open)
					{
						_inMessage = false;
						break;
					}
					e = _messageEventQueue.Dequeue();
				}
				bool flag = true;
			}
		}

		private void messages(MessageEventArgs e)
		{
			try
			{
				this.OnMessage.Emit(this, e);
			}
			catch (Exception ex)
			{
				_logger.Error(ex.ToString());
				error("An error has occurred during an OnMessage event.", ex);
			}
			lock (_forMessageEventQueue)
			{
				if (_messageEventQueue.Count == 0 || _readyState != WebSocketState.Open)
				{
					_inMessage = false;
					return;
				}
				e = _messageEventQueue.Dequeue();
			}
			ThreadPool.QueueUserWorkItem(delegate
			{
				messages(e);
			});
		}

		private void open()
		{
			_inMessage = true;
			startReceiving();
			try
			{
				this.OnOpen.Emit(this, EventArgs.Empty);
			}
			catch (Exception ex)
			{
				_logger.Error(ex.ToString());
				error("An error has occurred during the OnOpen event.", ex);
			}
			MessageEventArgs obj = null;
			lock (_forMessageEventQueue)
			{
				if (_messageEventQueue.Count == 0 || _readyState != WebSocketState.Open)
				{
					_inMessage = false;
					return;
				}
				obj = _messageEventQueue.Dequeue();
			}
			_message.BeginInvoke(obj, delegate(IAsyncResult ar)
			{
				_message.EndInvoke(ar);
			}, null);
		}

		private bool ping(byte[] data)
		{
			if (_readyState != WebSocketState.Open)
			{
				return false;
			}
			ManualResetEvent pongReceived = _pongReceived;
			if (pongReceived == null)
			{
				return false;
			}
			lock (_forPing)
			{
				try
				{
					pongReceived.Reset();
					if (!send(Fin.Final, Opcode.Ping, data, compressed: false))
					{
						return false;
					}
					return pongReceived.WaitOne(_waitTime);
				}
				catch (ObjectDisposedException)
				{
					return false;
				}
			}
		}

		private bool processCloseFrame(WebSocketFrame frame)
		{
			PayloadData payloadData = frame.PayloadData;
			close(payloadData, !payloadData.HasReservedCode, receive: false, received: true);
			return false;
		}

		private void processCookies(WebSocketSharp.Net.CookieCollection cookies)
		{
			if (cookies.Count != 0)
			{
				_cookies.SetOrRemove(cookies);
			}
		}

		private bool processDataFrame(WebSocketFrame frame)
		{
			enqueueToMessageEventQueue(frame.IsCompressed ? new MessageEventArgs(frame.Opcode, frame.PayloadData.ApplicationData.Decompress(_compression)) : new MessageEventArgs(frame));
			return true;
		}

		private bool processFragmentFrame(WebSocketFrame frame)
		{
			if (!_inContinuation)
			{
				if (frame.IsContinuation)
				{
					return true;
				}
				_fragmentsOpcode = frame.Opcode;
				_fragmentsCompressed = frame.IsCompressed;
				_fragmentsBuffer = new MemoryStream();
				_inContinuation = true;
			}
			_fragmentsBuffer.WriteBytes(frame.PayloadData.ApplicationData, 1024);
			if (frame.IsFinal)
			{
				using (_fragmentsBuffer)
				{
					byte[] rawData = (_fragmentsCompressed ? _fragmentsBuffer.DecompressToArray(_compression) : _fragmentsBuffer.ToArray());
					enqueueToMessageEventQueue(new MessageEventArgs(_fragmentsOpcode, rawData));
				}
				_fragmentsBuffer = null;
				_inContinuation = false;
			}
			return true;
		}

		private bool processPingFrame(WebSocketFrame frame)
		{
			_logger.Trace("A ping was received.");
			WebSocketFrame webSocketFrame = WebSocketFrame.CreatePongFrame(frame.PayloadData, _client);
			lock (_forState)
			{
				if (_readyState != WebSocketState.Open)
				{
					_logger.Error("The connection is closing.");
					return true;
				}
				if (!sendBytes(webSocketFrame.ToArray()))
				{
					return false;
				}
			}
			_logger.Trace("A pong to this ping has been sent.");
			if (_emitOnPing)
			{
				if (_client)
				{
					webSocketFrame.Unmask();
				}
				enqueueToMessageEventQueue(new MessageEventArgs(frame));
			}
			return true;
		}

		private bool processPongFrame(WebSocketFrame frame)
		{
			_logger.Trace("A pong was received.");
			try
			{
				_pongReceived.Set();
			}
			catch (NullReferenceException ex)
			{
				_logger.Error(ex.Message);
				_logger.Debug(ex.ToString());
				return false;
			}
			catch (ObjectDisposedException ex2)
			{
				_logger.Error(ex2.Message);
				_logger.Debug(ex2.ToString());
				return false;
			}
			_logger.Trace("It has been signaled.");
			return true;
		}

		private bool processReceivedFrame(WebSocketFrame frame)
		{
			if (!checkReceivedFrame(frame, out var text))
			{
				throw new WebSocketException(CloseStatusCode.ProtocolError, text);
			}
			frame.Unmask();
			return frame.IsFragment ? processFragmentFrame(frame) : (frame.IsData ? processDataFrame(frame) : (frame.IsPing ? processPingFrame(frame) : (frame.IsPong ? processPongFrame(frame) : (frame.IsClose ? processCloseFrame(frame) : processUnsupportedFrame(frame)))));
		}

		private void processSecWebSocketExtensionsClientHeader(string value)
		{
			if (value == null)
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder(80);
			bool flag = false;
			foreach (string item in value.SplitHeaderValue(','))
			{
				string text = item.Trim();
				if (text.Length != 0 && !flag && text.IsCompressionExtension(CompressionMethod.Deflate))
				{
					_compression = CompressionMethod.Deflate;
					stringBuilder.AppendFormat("{0}, ", _compression.ToExtensionString("client_no_context_takeover", "server_no_context_takeover"));
					flag = true;
				}
			}
			int length = stringBuilder.Length;
			if (length > 2)
			{
				stringBuilder.Length = length - 2;
				_extensions = stringBuilder.ToString();
			}
		}

		private void processSecWebSocketExtensionsServerHeader(string value)
		{
			if (value == null)
			{
				_compression = CompressionMethod.None;
			}
			else
			{
				_extensions = value;
			}
		}

		private void processSecWebSocketProtocolClientHeader(IEnumerable<string> values)
		{
			if (!values.Contains((string val) => val == _protocol))
			{
				_protocol = null;
			}
		}

		private bool processUnsupportedFrame(WebSocketFrame frame)
		{
			_logger.Fatal("An unsupported frame:" + frame.PrintToString(dumped: false));
			fatal("There is no way to handle it.", CloseStatusCode.PolicyViolation);
			return false;
		}

		private void refuseHandshake(CloseStatusCode code, string reason)
		{
			_readyState = WebSocketState.Closing;
			HttpResponse response = createHandshakeFailureResponse(WebSocketSharp.Net.HttpStatusCode.BadRequest);
			sendHttpResponse(response);
			releaseServerResources();
			_readyState = WebSocketState.Closed;
			CloseEventArgs e = new CloseEventArgs((ushort)code, reason, clean: false);
			try
			{
				this.OnClose.Emit(this, e);
			}
			catch (Exception ex)
			{
				_logger.Error(ex.Message);
				_logger.Debug(ex.ToString());
			}
		}

		private void releaseClientResources()
		{
			if (_stream != null)
			{
				_stream.Dispose();
				_stream = null;
			}
			if (_tcpClient != null)
			{
				_tcpClient.Close();
				_tcpClient = null;
			}
		}

		private void releaseCommonResources()
		{
			if (_fragmentsBuffer != null)
			{
				_fragmentsBuffer.Dispose();
				_fragmentsBuffer = null;
				_inContinuation = false;
			}
			if (_pongReceived != null)
			{
				_pongReceived.Close();
				_pongReceived = null;
			}
			if (_receivingExited != null)
			{
				_receivingExited.Close();
				_receivingExited = null;
			}
		}

		private void releaseResources()
		{
			if (_client)
			{
				releaseClientResources();
			}
			else
			{
				releaseServerResources();
			}
			releaseCommonResources();
		}

		private void releaseServerResources()
		{
			if (_closeContext != null)
			{
				_closeContext();
				_closeContext = null;
				_stream = null;
				_context = null;
			}
		}

		private bool send(Opcode opcode, Stream stream)
		{
			lock (_forSend)
			{
				Stream stream2 = stream;
				bool flag = false;
				bool flag2 = false;
				try
				{
					if (_compression != 0)
					{
						stream = stream.Compress(_compression);
						flag = true;
					}
					flag2 = send(opcode, stream, flag);
					if (!flag2)
					{
						error("A send has been interrupted.", null);
					}
				}
				catch (Exception ex)
				{
					_logger.Error(ex.ToString());
					error("An error has occurred during a send.", ex);
				}
				finally
				{
					if (flag)
					{
						stream.Dispose();
					}
					stream2.Dispose();
				}
				return flag2;
			}
		}

		private bool send(Opcode opcode, Stream stream, bool compressed)
		{
			long length = stream.Length;
			if (length == 0)
			{
				return send(Fin.Final, opcode, EmptyBytes, compressed: false);
			}
			long num = length / FragmentLength;
			int num2 = (int)(length % FragmentLength);
			byte[] array = null;
			switch (num)
			{
			case 0L:
				array = new byte[num2];
				return stream.Read(array, 0, num2) == num2 && send(Fin.Final, opcode, array, compressed);
			case 1L:
				if (num2 == 0)
				{
					array = new byte[FragmentLength];
					return stream.Read(array, 0, FragmentLength) == FragmentLength && send(Fin.Final, opcode, array, compressed);
				}
				break;
			}
			array = new byte[FragmentLength];
			if (stream.Read(array, 0, FragmentLength) != FragmentLength || !send(Fin.More, opcode, array, compressed))
			{
				return false;
			}
			long num3 = ((num2 == 0) ? (num - 2) : (num - 1));
			for (long num4 = 0L; num4 < num3; num4++)
			{
				if (stream.Read(array, 0, FragmentLength) != FragmentLength || !send(Fin.More, Opcode.Cont, array, compressed: false))
				{
					return false;
				}
			}
			if (num2 == 0)
			{
				num2 = FragmentLength;
			}
			else
			{
				array = new byte[num2];
			}
			return stream.Read(array, 0, num2) == num2 && send(Fin.Final, Opcode.Cont, array, compressed: false);
		}

		private bool send(Fin fin, Opcode opcode, byte[] data, bool compressed)
		{
			lock (_forState)
			{
				if (_readyState != WebSocketState.Open)
				{
					_logger.Error("The connection is closing.");
					return false;
				}
				WebSocketFrame webSocketFrame = new WebSocketFrame(fin, opcode, data, compressed, _client);
				return sendBytes(webSocketFrame.ToArray());
			}
		}

		private void sendAsync(Opcode opcode, Stream stream, Action<bool> completed)
		{
			Func<Opcode, Stream, bool> sender = send;
			sender.BeginInvoke(opcode, stream, delegate(IAsyncResult ar)
			{
				try
				{
					bool obj = sender.EndInvoke(ar);
					if (completed != null)
					{
						completed(obj);
					}
				}
				catch (Exception ex)
				{
					_logger.Error(ex.ToString());
					error("An error has occurred during the callback for an async send.", ex);
				}
			}, null);
		}

		private bool sendBytes(byte[] bytes)
		{
			try
			{
				_stream.Write(bytes, 0, bytes.Length);
			}
			catch (Exception ex)
			{
				_logger.Error(ex.Message);
				_logger.Debug(ex.ToString());
				return false;
			}
			return true;
		}

		private HttpResponse sendHandshakeRequest()
		{
			HttpRequest httpRequest = createHandshakeRequest();
			HttpResponse httpResponse = sendHttpRequest(httpRequest, 90000);
			if (httpResponse.IsUnauthorized)
			{
				string text = httpResponse.Headers["WWW-Authenticate"];
				_logger.Warn($"Received an authentication requirement for '{text}'.");
				if (text.IsNullOrEmpty())
				{
					_logger.Error("No authentication challenge is specified.");
					return httpResponse;
				}
				_authChallenge = AuthenticationChallenge.Parse(text);
				if (_authChallenge == null)
				{
					_logger.Error("An invalid authentication challenge is specified.");
					return httpResponse;
				}
				if (_credentials != null && (!_preAuth || _authChallenge.Scheme == WebSocketSharp.Net.AuthenticationSchemes.Digest))
				{
					if (httpResponse.HasConnectionClose)
					{
						releaseClientResources();
						setClientStream();
					}
					AuthenticationResponse authenticationResponse = new AuthenticationResponse(_authChallenge, _credentials, _nonceCount);
					_nonceCount = authenticationResponse.NonceCount;
					httpRequest.Headers["Authorization"] = authenticationResponse.ToString();
					httpResponse = sendHttpRequest(httpRequest, 15000);
				}
			}
			if (httpResponse.IsRedirect)
			{
				string text2 = httpResponse.Headers["Location"];
				_logger.Warn($"Received a redirection to '{text2}'.");
				if (_enableRedirection)
				{
					if (text2.IsNullOrEmpty())
					{
						_logger.Error("No url to redirect is located.");
						return httpResponse;
					}
					if (!text2.TryCreateWebSocketUri(out var result, out var text3))
					{
						_logger.Error("An invalid url to redirect is located: " + text3);
						return httpResponse;
					}
					releaseClientResources();
					_uri = result;
					_secure = result.Scheme == "wss";
					setClientStream();
					return sendHandshakeRequest();
				}
			}
			return httpResponse;
		}

		private HttpResponse sendHttpRequest(HttpRequest request, int millisecondsTimeout)
		{
			_logger.Debug("A request to the server:\n" + request.ToString());
			HttpResponse response = request.GetResponse(_stream, millisecondsTimeout);
			_logger.Debug("A response to this request:\n" + response.ToString());
			return response;
		}

		private bool sendHttpResponse(HttpResponse response)
		{
			_logger.Debug($"A response to {_context.UserEndPoint}:\n{response}");
			return sendBytes(response.ToByteArray());
		}

		private void sendProxyConnectRequest()
		{
			HttpRequest httpRequest = HttpRequest.CreateConnectRequest(_uri);
			HttpResponse httpResponse = sendHttpRequest(httpRequest, 90000);
			if (httpResponse.IsProxyAuthenticationRequired)
			{
				string text = httpResponse.Headers["Proxy-Authenticate"];
				_logger.Warn($"Received a proxy authentication requirement for '{text}'.");
				if (text.IsNullOrEmpty())
				{
					throw new WebSocketException("No proxy authentication challenge is specified.");
				}
				AuthenticationChallenge authenticationChallenge = AuthenticationChallenge.Parse(text);
				if (authenticationChallenge == null)
				{
					throw new WebSocketException("An invalid proxy authentication challenge is specified.");
				}
				if (_proxyCredentials != null)
				{
					if (httpResponse.HasConnectionClose)
					{
						releaseClientResources();
						_tcpClient = new TcpClient(_proxyUri.DnsSafeHost, _proxyUri.Port);
						_stream = _tcpClient.GetStream();
					}
					AuthenticationResponse authenticationResponse = new AuthenticationResponse(authenticationChallenge, _proxyCredentials, 0u);
					httpRequest.Headers["Proxy-Authorization"] = authenticationResponse.ToString();
					httpResponse = sendHttpRequest(httpRequest, 15000);
				}
				if (httpResponse.IsProxyAuthenticationRequired)
				{
					throw new WebSocketException("A proxy authentication is required.");
				}
			}
			if (httpResponse.StatusCode[0] != '2')
			{
				throw new WebSocketException("The proxy has failed a connection to the requested host and port.");
			}
		}

		private void setClientStream()
		{
			if (_proxyUri != null)
			{
				_tcpClient = new TcpClient(_proxyUri.DnsSafeHost, _proxyUri.Port);
				_stream = _tcpClient.GetStream();
				sendProxyConnectRequest();
			}
			else
			{
				_tcpClient = new TcpClient(_uri.DnsSafeHost, _uri.Port);
				_stream = _tcpClient.GetStream();
			}
			if (_secure)
			{
				ClientSslConfiguration sslConfiguration = getSslConfiguration();
				string targetHost = sslConfiguration.TargetHost;
				if (targetHost != _uri.DnsSafeHost)
				{
					throw new WebSocketException(CloseStatusCode.TlsHandshakeFailure, "An invalid host name is specified.");
				}
				try
				{
					SslStream sslStream = new SslStream(_stream, leaveInnerStreamOpen: false, sslConfiguration.ServerCertificateValidationCallback, sslConfiguration.ClientCertificateSelectionCallback);
					sslStream.AuthenticateAsClient(targetHost, sslConfiguration.ClientCertificates, sslConfiguration.EnabledSslProtocols, sslConfiguration.CheckCertificateRevocation);
					_stream = sslStream;
				}
				catch (Exception innerException)
				{
					throw new WebSocketException(CloseStatusCode.TlsHandshakeFailure, innerException);
				}
			}
		}

		private void startReceiving()
		{
			if (_messageEventQueue.Count > 0)
			{
				_messageEventQueue.Clear();
			}
			_pongReceived = new ManualResetEvent(initialState: false);
			_receivingExited = new ManualResetEvent(initialState: false);
			Action receive = null;
			receive = delegate
			{
				WebSocketFrame.ReadFrameAsync(_stream, unmask: false, delegate(WebSocketFrame frame)
				{
					if (!processReceivedFrame(frame) || _readyState == WebSocketState.Closed)
					{
						_receivingExited?.Set();
					}
					else
					{
						receive();
						if (!_inMessage && HasMessage && _readyState == WebSocketState.Open)
						{
							message();
						}
					}
				}, delegate(Exception ex)
				{
					_logger.Fatal(ex.ToString());
					fatal("An exception has occurred while receiving.", ex);
				});
			};
			receive();
		}

		private bool validateSecWebSocketAcceptHeader(string value)
		{
			return value != null && value == CreateResponseKey(_base64Key);
		}

		private bool validateSecWebSocketExtensionsServerHeader(string value)
		{
			if (value == null)
			{
				return true;
			}
			if (value.Length == 0)
			{
				return false;
			}
			if (!_extensionsRequested)
			{
				return false;
			}
			bool flag = _compression != CompressionMethod.None;
			foreach (string item in value.SplitHeaderValue(','))
			{
				string text = item.Trim();
				if (flag && text.IsCompressionExtension(_compression))
				{
					if (!text.Contains("server_no_context_takeover"))
					{
						_logger.Error("The server hasn't sent back 'server_no_context_takeover'.");
						return false;
					}
					if (!text.Contains("client_no_context_takeover"))
					{
						_logger.Warn("The server hasn't sent back 'client_no_context_takeover'.");
					}
					string method = _compression.ToExtensionString();
					if (text.SplitHeaderValue(';').Contains(delegate(string t)
					{
						t = t.Trim();
						return t != method && t != "server_no_context_takeover" && t != "client_no_context_takeover";
					}))
					{
						return false;
					}
					continue;
				}
				return false;
			}
			return true;
		}

		private bool validateSecWebSocketProtocolServerHeader(string value)
		{
			if (value == null)
			{
				return !_protocolsRequested;
			}
			if (value.Length == 0)
			{
				return false;
			}
			return _protocolsRequested && _protocols.Contains((string p) => p == value);
		}

		private bool validateSecWebSocketVersionServerHeader(string value)
		{
			return value == null || value == "13";
		}

		internal void Close(HttpResponse response)
		{
			_readyState = WebSocketState.Closing;
			sendHttpResponse(response);
			releaseServerResources();
			_readyState = WebSocketState.Closed;
		}

		internal void Close(WebSocketSharp.Net.HttpStatusCode code)
		{
			Close(createHandshakeFailureResponse(code));
		}

		internal void Close(PayloadData payloadData, byte[] frameAsBytes)
		{
			lock (_forState)
			{
				if (_readyState == WebSocketState.Closing)
				{
					_logger.Info("The closing is already in progress.");
					return;
				}
				if (_readyState == WebSocketState.Closed)
				{
					_logger.Info("The connection has already been closed.");
					return;
				}
				_readyState = WebSocketState.Closing;
			}
			_logger.Trace("Begin closing the connection.");
			bool flag = frameAsBytes != null && sendBytes(frameAsBytes);
			bool flag2 = flag && _receivingExited != null && _receivingExited.WaitOne(_waitTime);
			bool flag3 = flag && flag2;
			_logger.Debug($"Was clean?: {flag3}\n  sent: {flag}\n  received: {flag2}");
			releaseServerResources();
			releaseCommonResources();
			_logger.Trace("End closing the connection.");
			_readyState = WebSocketState.Closed;
			CloseEventArgs e = new CloseEventArgs(payloadData, flag3);
			try
			{
				this.OnClose.Emit(this, e);
			}
			catch (Exception ex)
			{
				_logger.Error(ex.Message);
				_logger.Debug(ex.ToString());
			}
		}

		internal static string CreateBase64Key()
		{
			byte[] array = new byte[16];
			RandomNumber.GetBytes(array);
			return Convert.ToBase64String(array);
		}

		internal static string CreateResponseKey(string base64Key)
		{
			StringBuilder stringBuilder = new StringBuilder(base64Key, 64);
			stringBuilder.Append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
			SHA1 sHA = new SHA1CryptoServiceProvider();
			byte[] inArray = sHA.ComputeHash(stringBuilder.ToString().GetUTF8EncodedBytes());
			return Convert.ToBase64String(inArray);
		}

		internal void InternalAccept()
		{
			try
			{
				if (!acceptHandshake())
				{
					return;
				}
			}
			catch (Exception ex)
			{
				_logger.Fatal(ex.Message);
				_logger.Debug(ex.ToString());
				string text = "An exception has occurred while attempting to accept.";
				fatal(text, ex);
				return;
			}
			_readyState = WebSocketState.Open;
			open();
		}

		internal bool Ping(byte[] frameAsBytes, TimeSpan timeout)
		{
			if (_readyState != WebSocketState.Open)
			{
				return false;
			}
			ManualResetEvent pongReceived = _pongReceived;
			if (pongReceived == null)
			{
				return false;
			}
			lock (_forPing)
			{
				try
				{
					pongReceived.Reset();
					lock (_forState)
					{
						if (_readyState != WebSocketState.Open)
						{
							return false;
						}
						if (!sendBytes(frameAsBytes))
						{
							return false;
						}
					}
					return pongReceived.WaitOne(timeout);
				}
				catch (ObjectDisposedException)
				{
					return false;
				}
			}
		}

		internal void Send(Opcode opcode, byte[] data, Dictionary<CompressionMethod, byte[]> cache)
		{
			lock (_forSend)
			{
				lock (_forState)
				{
					if (_readyState != WebSocketState.Open)
					{
						_logger.Error("The connection is closing.");
						return;
					}
					if (!cache.TryGetValue(_compression, out var value))
					{
						value = new WebSocketFrame(Fin.Final, opcode, data.Compress(_compression), _compression != CompressionMethod.None, mask: false).ToArray();
						cache.Add(_compression, value);
					}
					sendBytes(value);
				}
			}
		}

		internal void Send(Opcode opcode, Stream stream, Dictionary<CompressionMethod, Stream> cache)
		{
			lock (_forSend)
			{
				if (!cache.TryGetValue(_compression, out var value))
				{
					value = stream.Compress(_compression);
					cache.Add(_compression, value);
				}
				else
				{
					value.Position = 0L;
				}
				send(opcode, value, _compression != CompressionMethod.None);
			}
		}

		public void Accept()
		{
			if (_client)
			{
				string text = "This instance is a client.";
				throw new InvalidOperationException(text);
			}
			if (_readyState == WebSocketState.Closing)
			{
				string text2 = "The close process is in progress.";
				throw new InvalidOperationException(text2);
			}
			if (_readyState == WebSocketState.Closed)
			{
				string text3 = "The connection has already been closed.";
				throw new InvalidOperationException(text3);
			}
			if (accept())
			{
				open();
			}
		}

		public void AcceptAsync()
		{
			if (_client)
			{
				string text = "This instance is a client.";
				throw new InvalidOperationException(text);
			}
			if (_readyState == WebSocketState.Closing)
			{
				string text2 = "The close process is in progress.";
				throw new InvalidOperationException(text2);
			}
			if (_readyState == WebSocketState.Closed)
			{
				string text3 = "The connection has already been closed.";
				throw new InvalidOperationException(text3);
			}
			Func<bool> acceptor = accept;
			acceptor.BeginInvoke(delegate(IAsyncResult ar)
			{
				if (acceptor.EndInvoke(ar))
				{
					open();
				}
			}, null);
		}

		public void Close()
		{
			close(1005, string.Empty);
		}

		public void Close(ushort code)
		{
			if (!code.IsCloseStatusCode())
			{
				string text = "Less than 1000 or greater than 4999.";
				throw new ArgumentOutOfRangeException("code", text);
			}
			if (_client && code == 1011)
			{
				string text2 = "1011 cannot be used.";
				throw new ArgumentException(text2, "code");
			}
			if (!_client && code == 1010)
			{
				string text3 = "1010 cannot be used.";
				throw new ArgumentException(text3, "code");
			}
			close(code, string.Empty);
		}

		public void Close(CloseStatusCode code)
		{
			if (_client && code == CloseStatusCode.ServerError)
			{
				string text = "ServerError cannot be used.";
				throw new ArgumentException(text, "code");
			}
			if (!_client && code == CloseStatusCode.MandatoryExtension)
			{
				string text2 = "MandatoryExtension cannot be used.";
				throw new ArgumentException(text2, "code");
			}
			close((ushort)code, string.Empty);
		}

		public void Close(ushort code, string reason)
		{
			if (!code.IsCloseStatusCode())
			{
				string text = "Less than 1000 or greater than 4999.";
				throw new ArgumentOutOfRangeException("code", text);
			}
			if (_client && code == 1011)
			{
				string text2 = "1011 cannot be used.";
				throw new ArgumentException(text2, "code");
			}
			if (!_client && code == 1010)
			{
				string text3 = "1010 cannot be used.";
				throw new ArgumentException(text3, "code");
			}
			if (reason.IsNullOrEmpty())
			{
				close(code, string.Empty);
				return;
			}
			if (code == 1005)
			{
				string text4 = "1005 cannot be used.";
				throw new ArgumentException(text4, "code");
			}
			if (!reason.TryGetUTF8EncodedBytes(out var bytes))
			{
				string text5 = "It could not be UTF-8-encoded.";
				throw new ArgumentException(text5, "reason");
			}
			if (bytes.Length > 123)
			{
				string text6 = "Its size is greater than 123 bytes.";
				throw new ArgumentOutOfRangeException("reason", text6);
			}
			close(code, reason);
		}

		public void Close(CloseStatusCode code, string reason)
		{
			if (_client && code == CloseStatusCode.ServerError)
			{
				string text = "ServerError cannot be used.";
				throw new ArgumentException(text, "code");
			}
			if (!_client && code == CloseStatusCode.MandatoryExtension)
			{
				string text2 = "MandatoryExtension cannot be used.";
				throw new ArgumentException(text2, "code");
			}
			if (reason.IsNullOrEmpty())
			{
				close((ushort)code, string.Empty);
				return;
			}
			if (code == CloseStatusCode.NoStatus)
			{
				string text3 = "NoStatus cannot be used.";
				throw new ArgumentException(text3, "code");
			}
			if (!reason.TryGetUTF8EncodedBytes(out var bytes))
			{
				string text4 = "It could not be UTF-8-encoded.";
				throw new ArgumentException(text4, "reason");
			}
			if (bytes.Length > 123)
			{
				string text5 = "Its size is greater than 123 bytes.";
				throw new ArgumentOutOfRangeException("reason", text5);
			}
			close((ushort)code, reason);
		}

		public void CloseAsync()
		{
			closeAsync(1005, string.Empty);
		}

		public void CloseAsync(ushort code)
		{
			if (!code.IsCloseStatusCode())
			{
				string text = "Less than 1000 or greater than 4999.";
				throw new ArgumentOutOfRangeException("code", text);
			}
			if (_client && code == 1011)
			{
				string text2 = "1011 cannot be used.";
				throw new ArgumentException(text2, "code");
			}
			if (!_client && code == 1010)
			{
				string text3 = "1010 cannot be used.";
				throw new ArgumentException(text3, "code");
			}
			closeAsync(code, string.Empty);
		}

		public void CloseAsync(CloseStatusCode code)
		{
			if (_client && code == CloseStatusCode.ServerError)
			{
				string text = "ServerError cannot be used.";
				throw new ArgumentException(text, "code");
			}
			if (!_client && code == CloseStatusCode.MandatoryExtension)
			{
				string text2 = "MandatoryExtension cannot be used.";
				throw new ArgumentException(text2, "code");
			}
			closeAsync((ushort)code, string.Empty);
		}

		public void CloseAsync(ushort code, string reason)
		{
			if (!code.IsCloseStatusCode())
			{
				string text = "Less than 1000 or greater than 4999.";
				throw new ArgumentOutOfRangeException("code", text);
			}
			if (_client && code == 1011)
			{
				string text2 = "1011 cannot be used.";
				throw new ArgumentException(text2, "code");
			}
			if (!_client && code == 1010)
			{
				string text3 = "1010 cannot be used.";
				throw new ArgumentException(text3, "code");
			}
			if (reason.IsNullOrEmpty())
			{
				closeAsync(code, string.Empty);
				return;
			}
			if (code == 1005)
			{
				string text4 = "1005 cannot be used.";
				throw new ArgumentException(text4, "code");
			}
			if (!reason.TryGetUTF8EncodedBytes(out var bytes))
			{
				string text5 = "It could not be UTF-8-encoded.";
				throw new ArgumentException(text5, "reason");
			}
			if (bytes.Length > 123)
			{
				string text6 = "Its size is greater than 123 bytes.";
				throw new ArgumentOutOfRangeException("reason", text6);
			}
			closeAsync(code, reason);
		}

		public void CloseAsync(CloseStatusCode code, string reason)
		{
			if (_client && code == CloseStatusCode.ServerError)
			{
				string text = "ServerError cannot be used.";
				throw new ArgumentException(text, "code");
			}
			if (!_client && code == CloseStatusCode.MandatoryExtension)
			{
				string text2 = "MandatoryExtension cannot be used.";
				throw new ArgumentException(text2, "code");
			}
			if (reason.IsNullOrEmpty())
			{
				closeAsync((ushort)code, string.Empty);
				return;
			}
			if (code == CloseStatusCode.NoStatus)
			{
				string text3 = "NoStatus cannot be used.";
				throw new ArgumentException(text3, "code");
			}
			if (!reason.TryGetUTF8EncodedBytes(out var bytes))
			{
				string text4 = "It could not be UTF-8-encoded.";
				throw new ArgumentException(text4, "reason");
			}
			if (bytes.Length > 123)
			{
				string text5 = "Its size is greater than 123 bytes.";
				throw new ArgumentOutOfRangeException("reason", text5);
			}
			closeAsync((ushort)code, reason);
		}

		public void Connect()
		{
			if (!_client)
			{
				string text = "This instance is not a client.";
				throw new InvalidOperationException(text);
			}
			if (_readyState == WebSocketState.Closing)
			{
				string text2 = "The close process is in progress.";
				throw new InvalidOperationException(text2);
			}
			if (_retryCountForConnect > _maxRetryCountForConnect)
			{
				string text3 = "A series of reconnecting has failed.";
				throw new InvalidOperationException(text3);
			}
			if (connect())
			{
				open();
			}
		}

		public void ConnectAsync()
		{
			if (!_client)
			{
				string text = "This instance is not a client.";
				throw new InvalidOperationException(text);
			}
			if (_readyState == WebSocketState.Closing)
			{
				string text2 = "The close process is in progress.";
				throw new InvalidOperationException(text2);
			}
			if (_retryCountForConnect > _maxRetryCountForConnect)
			{
				string text3 = "A series of reconnecting has failed.";
				throw new InvalidOperationException(text3);
			}
			Func<bool> connector = connect;
			connector.BeginInvoke(delegate(IAsyncResult ar)
			{
				if (connector.EndInvoke(ar))
				{
					open();
				}
			}, null);
		}

		public bool Ping()
		{
			return ping(EmptyBytes);
		}

		public bool Ping(string message)
		{
			if (message.IsNullOrEmpty())
			{
				return ping(EmptyBytes);
			}
			if (!message.TryGetUTF8EncodedBytes(out var bytes))
			{
				string text = "It could not be UTF-8-encoded.";
				throw new ArgumentException(text, "message");
			}
			if (bytes.Length > 125)
			{
				string text2 = "Its size is greater than 125 bytes.";
				throw new ArgumentOutOfRangeException("message", text2);
			}
			return ping(bytes);
		}

		public void Send(byte[] data)
		{
			if (_readyState != WebSocketState.Open)
			{
				string text = "The current state of the connection is not Open.";
				throw new InvalidOperationException(text);
			}
			if (data == null)
			{
				throw new ArgumentNullException("data");
			}
			send(Opcode.Binary, new MemoryStream(data));
		}

		public void Send(FileInfo fileInfo)
		{
			if (_readyState != WebSocketState.Open)
			{
				string text = "The current state of the connection is not Open.";
				throw new InvalidOperationException(text);
			}
			if (fileInfo == null)
			{
				throw new ArgumentNullException("fileInfo");
			}
			if (!fileInfo.Exists)
			{
				string text2 = "The file does not exist.";
				throw new ArgumentException(text2, "fileInfo");
			}
			if (!fileInfo.TryOpenRead(out var fileStream))
			{
				string text3 = "The file could not be opened.";
				throw new ArgumentException(text3, "fileInfo");
			}
			send(Opcode.Binary, fileStream);
		}

		public void Send(string data)
		{
			if (_readyState != WebSocketState.Open)
			{
				string text = "The current state of the connection is not Open.";
				throw new InvalidOperationException(text);
			}
			if (data == null)
			{
				throw new ArgumentNullException("data");
			}
			if (!data.TryGetUTF8EncodedBytes(out var bytes))
			{
				string text2 = "It could not be UTF-8-encoded.";
				throw new ArgumentException(text2, "data");
			}
			send(Opcode.Text, new MemoryStream(bytes));
		}

		public void Send(Stream stream, int length)
		{
			if (_readyState != WebSocketState.Open)
			{
				string text = "The current state of the connection is not Open.";
				throw new InvalidOperationException(text);
			}
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			if (!stream.CanRead)
			{
				string text2 = "It cannot be read.";
				throw new ArgumentException(text2, "stream");
			}
			if (length < 1)
			{
				string text3 = "Less than 1.";
				throw new ArgumentException(text3, "length");
			}
			byte[] array = stream.ReadBytes(length);
			int num = array.Length;
			if (num == 0)
			{
				string text4 = "No data could be read from it.";
				throw new ArgumentException(text4, "stream");
			}
			if (num < length)
			{
				_logger.Warn($"Only {num} byte(s) of data could be read from the stream.");
			}
			send(Opcode.Binary, new MemoryStream(array));
		}

		public void SendAsync(byte[] data, Action<bool> completed)
		{
			if (_readyState != WebSocketState.Open)
			{
				string text = "The current state of the connection is not Open.";
				throw new InvalidOperationException(text);
			}
			if (data == null)
			{
				throw new ArgumentNullException("data");
			}
			sendAsync(Opcode.Binary, new MemoryStream(data), completed);
		}

		public void SendAsync(FileInfo fileInfo, Action<bool> completed)
		{
			if (_readyState != WebSocketState.Open)
			{
				string text = "The current state of the connection is not Open.";
				throw new InvalidOperationException(text);
			}
			if (fileInfo == null)
			{
				throw new ArgumentNullException("fileInfo");
			}
			if (!fileInfo.Exists)
			{
				string text2 = "The file does not exist.";
				throw new ArgumentException(text2, "fileInfo");
			}
			if (!fileInfo.TryOpenRead(out var fileStream))
			{
				string text3 = "The file could not be opened.";
				throw new ArgumentException(text3, "fileInfo");
			}
			sendAsync(Opcode.Binary, fileStream, completed);
		}

		public void SendAsync(string data, Action<bool> completed)
		{
			if (_readyState != WebSocketState.Open)
			{
				string text = "The current state of the connection is not Open.";
				throw new InvalidOperationException(text);
			}
			if (data == null)
			{
				throw new ArgumentNullException("data");
			}
			if (!data.TryGetUTF8EncodedBytes(out var bytes))
			{
				string text2 = "It could not be UTF-8-encoded.";
				throw new ArgumentException(text2, "data");
			}
			sendAsync(Opcode.Text, new MemoryStream(bytes), completed);
		}

		public void SendAsync(Stream stream, int length, Action<bool> completed)
		{
			if (_readyState != WebSocketState.Open)
			{
				string text = "The current state of the connection is not Open.";
				throw new InvalidOperationException(text);
			}
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			if (!stream.CanRead)
			{
				string text2 = "It cannot be read.";
				throw new ArgumentException(text2, "stream");
			}
			if (length < 1)
			{
				string text3 = "Less than 1.";
				throw new ArgumentException(text3, "length");
			}
			byte[] array = stream.ReadBytes(length);
			int num = array.Length;
			if (num == 0)
			{
				string text4 = "No data could be read from it.";
				throw new ArgumentException(text4, "stream");
			}
			if (num < length)
			{
				_logger.Warn($"Only {num} byte(s) of data could be read from the stream.");
			}
			sendAsync(Opcode.Binary, new MemoryStream(array), completed);
		}

		public void SetCookie(WebSocketSharp.Net.Cookie cookie)
		{
			string text = null;
			if (!_client)
			{
				text = "This instance is not a client.";
				throw new InvalidOperationException(text);
			}
			if (cookie == null)
			{
				throw new ArgumentNullException("cookie");
			}
			if (!canSet(out text))
			{
				_logger.Warn(text);
				return;
			}
			lock (_forState)
			{
				if (!canSet(out text))
				{
					_logger.Warn(text);
					return;
				}
				lock (_cookies.SyncRoot)
				{
					_cookies.SetOrRemove(cookie);
				}
			}
		}

		public void SetCredentials(string username, string password, bool preAuth)
		{
			string text = null;
			if (!_client)
			{
				text = "This instance is not a client.";
				throw new InvalidOperationException(text);
			}
			if (!username.IsNullOrEmpty() && (Ext.Contains(username, ':') || !username.IsText()))
			{
				text = "It contains an invalid character.";
				throw new ArgumentException(text, "username");
			}
			if (!password.IsNullOrEmpty() && !password.IsText())
			{
				text = "It contains an invalid character.";
				throw new ArgumentException(text, "password");
			}
			if (!canSet(out text))
			{
				_logger.Warn(text);
				return;
			}
			lock (_forState)
			{
				if (!canSet(out text))
				{
					_logger.Warn(text);
				}
				else if (username.IsNullOrEmpty())
				{
					_credentials = null;
					_preAuth = false;
				}
				else
				{
					_credentials = new WebSocketSharp.Net.NetworkCredential(username, password, _uri.PathAndQuery);
					_preAuth = preAuth;
				}
			}
		}

		public void SetProxy(string url, string username, string password)
		{
			string text = null;
			if (!_client)
			{
				text = "This instance is not a client.";
				throw new InvalidOperationException(text);
			}
			Uri result = null;
			if (!url.IsNullOrEmpty())
			{
				if (!Uri.TryCreate(url, UriKind.Absolute, out result))
				{
					text = "Not an absolute URI string.";
					throw new ArgumentException(text, "url");
				}
				if (result.Scheme != "http")
				{
					text = "The scheme part is not http.";
					throw new ArgumentException(text, "url");
				}
				if (result.Segments.Length > 1)
				{
					text = "It includes the path segments.";
					throw new ArgumentException(text, "url");
				}
			}
			if (!username.IsNullOrEmpty() && (Ext.Contains(username, ':') || !username.IsText()))
			{
				text = "It contains an invalid character.";
				throw new ArgumentException(text, "username");
			}
			if (!password.IsNullOrEmpty() && !password.IsText())
			{
				text = "It contains an invalid character.";
				throw new ArgumentException(text, "password");
			}
			if (!canSet(out text))
			{
				_logger.Warn(text);
				return;
			}
			lock (_forState)
			{
				if (!canSet(out text))
				{
					_logger.Warn(text);
				}
				else if (url.IsNullOrEmpty())
				{
					_proxyUri = null;
					_proxyCredentials = null;
				}
				else
				{
					_proxyUri = result;
					_proxyCredentials = ((!username.IsNullOrEmpty()) ? new WebSocketSharp.Net.NetworkCredential(username, password, $"{_uri.DnsSafeHost}:{_uri.Port}") : null);
				}
			}
		}

		void IDisposable.Dispose()
		{
			close(1001, string.Empty);
		}
	}
	public enum CloseStatusCode : ushort
	{
		Normal = 1000,
		Away = 1001,
		ProtocolError = 1002,
		UnsupportedData = 1003,
		Undefined = 1004,
		NoStatus = 1005,
		Abnormal = 1006,
		InvalidData = 1007,
		PolicyViolation = 1008,
		TooBig = 1009,
		MandatoryExtension = 1010,
		ServerError = 1011,
		TlsHandshakeFailure = 1015
	}
	internal enum Fin : byte
	{
		More,
		Final
	}
	internal enum Mask : byte
	{
		Off,
		On
	}
	internal enum Opcode : byte
	{
		Cont = 0,
		Text = 1,
		Binary = 2,
		Close = 8,
		Ping = 9,
		Pong = 10
	}
	internal class PayloadData : IEnumerable<byte>, IEnumerable
	{
		private byte[] _data;

		private long _extDataLength;

		private long _length;

		public static readonly PayloadData Empty;

		public static readonly ulong MaxLength;

		internal ushort Code => (ushort)((_length >= 2) ? _data.SubArray(0, 2).ToUInt16(ByteOrder.Big) : 1005);

		internal long ExtensionDataLength
		{
			get
			{
				return _extDataLength;
			}
			set
			{
				_extDataLength = value;
			}
		}

		internal bool HasReservedCode => _length >= 2 && Code.IsReserved();

		internal string Reason
		{
			get
			{
				if (_length <= 2)
				{
					return string.Empty;
				}
				byte[] bytes = _data.SubArray(2L, _length - 2);
				string s;
				return bytes.TryGetUTF8DecodedString(out s) ? s : string.Empty;
			}
		}

		public byte[] ApplicationData => (_extDataLength > 0) ? _data.SubArray(_extDataLength, _length - _extDataLength) : _data;

		public byte[] ExtensionData => (_extDataLength > 0) ? _data.SubArray(0L, _extDataLength) : WebSocket.EmptyBytes;

		public ulong Length => (ulong)_length;

		static PayloadData()
		{
			Empty = new PayloadData(WebSocket.EmptyBytes, 0L);
			MaxLength = 9223372036854775807uL;
		}

		internal PayloadData(byte[] data)
			: this(data, data.LongLength)
		{
		}

		internal PayloadData(byte[] data, long length)
		{
			_data = data;
			_length = length;
		}

		internal PayloadData(ushort code, string reason)
		{
			_data = code.Append(reason);
			_length = _data.LongLength;
		}

		internal void Mask(byte[] key)
		{
			for (long num = 0L; num < _length; num++)
			{
				_data[num] ^= key[num % 4];
			}
		}

		public IEnumerator<byte> GetEnumerator()
		{
			byte[] data = _data;
			for (int i = 0; i < data.Length; i++)
			{
				yield return data[i];
			}
		}

		public byte[] ToArray()
		{
			return _data;
		}

		public override string ToString()
		{
			return BitConverter.ToString(_data);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	internal enum Rsv : byte
	{
		Off,
		On
	}
	public enum CompressionMethod : byte
	{
		None,
		Deflate
	}
	public class WebSocketException : Exception
	{
		private CloseStatusCode _code;

		public CloseStatusCode Code => _code;

		internal WebSocketException()
			: this(CloseStatusCode.Abnormal, null, null)
		{
		}

		internal WebSocketException(Exception innerException)
			: this(CloseStatusCode.Abnormal, null, innerException)
		{
		}

		internal WebSocketException(string message)
			: this(CloseStatusCode.Abnormal, message, null)
		{
		}

		internal WebSocketException(CloseStatusCode code)
			: this(code, null, null)
		{
		}

		internal WebSocketException(string message, Exception innerException)
			: this(CloseStatusCode.Abnormal, message, innerException)
		{
		}

		internal WebSocketException(CloseStatusCode code, Exception innerException)
			: this(code, null, innerException)
		{
		}

		internal WebSocketException(CloseStatusCode code, string message)
			: this(code, message, null)
		{
		}

		internal WebSocketException(CloseStatusCode code, string message, Exception innerException)
			: base(message ?? code.GetMessage(), innerException)
		{
			_code = code;
		}
	}
	public class LogData
	{
		private StackFrame _caller;

		private DateTime _date;

		private LogLevel _level;

		private string _message;

		public StackFrame Caller => _caller;

		public DateTime Date => _date;

		public LogLevel Level => _level;

		public string Message => _message;

		internal LogData(LogLevel level, StackFrame caller, string message)
		{
			_level = level;
			_c