Decompiled source of AdminSystem v3.1.1

BepInEx/plugins/Hikaria.AdminSystem/Hikaria.AdminSystem.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using AIGraph;
using AK;
using Agents;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils;
using CellMenu;
using ChainedPuzzles;
using Clonesoft.Json;
using CullingSystem;
using Enemies;
using GameData;
using Gear;
using Globals;
using Hikaria.AdminSystem.Extensions;
using Hikaria.AdminSystem.Features.Player;
using Hikaria.AdminSystem.Features.Weapon;
using Hikaria.AdminSystem.Interfaces;
using Hikaria.AdminSystem.Managers;
using Hikaria.AdminSystem.Utilities;
using Hikaria.DevConsoleLite;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using Steamworks;
using TheArchive;
using TheArchive.Core;
using TheArchive.Core.Attributes;
using TheArchive.Core.Attributes.Feature.Settings;
using TheArchive.Core.FeaturesAPI;
using TheArchive.Core.FeaturesAPI.Components;
using TheArchive.Core.FeaturesAPI.Settings;
using TheArchive.Core.Localization;
using TheArchive.Core.Models;
using TheArchive.Core.ModulesAPI;
using TheArchive.Features.Dev;
using TheArchive.Features.Security;
using TheArchive.Interfaces;
using TheArchive.Loader;
using TheArchive.Utilities;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4a1b9f36-ece1-456d-8dda-ddac7b4821c8")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
}
namespace Hikaria.AdminSystem
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Hikaria.AdminSystem", "AdminSystem", "3.1.1")]
	public class EntryPoint : BasePlugin, IArchiveModule
	{
		public static class Groups
		{
			public static FeatureGroup ModuleGroup => FeatureGroups.GetOrCreateModuleGroup("Admin System", (Dictionary<Language, string>)null);

			public static FeatureGroup Item => ModuleGroup.GetOrCreateSubGroup("Item", false);

			public static FeatureGroup Weapon => ModuleGroup.GetOrCreateSubGroup("Weapon", false);

			public static FeatureGroup Player => ModuleGroup.GetOrCreateSubGroup("Player", false);

			public static FeatureGroup Enemy => ModuleGroup.GetOrCreateSubGroup("Enemy", false);

			public static FeatureGroup Misc => ModuleGroup.GetOrCreateSubGroup("Misc", false);

			public static FeatureGroup Security => ModuleGroup.GetOrCreateSubGroup("Security", false);

			public static FeatureGroup InLevel => ModuleGroup.GetOrCreateSubGroup("InLevel", false);

			static Groups()
			{
				Item.SetLanguage((Language)1, "物品");
				Item.SetLanguage((Language)0, "Item");
				Weapon.SetLanguage((Language)1, "武器");
				Weapon.SetLanguage((Language)0, "Weapon");
				Player.SetLanguage((Language)1, "玩家");
				Player.SetLanguage((Language)0, "Player");
				InLevel.SetLanguage((Language)1, "游戏内");
				InLevel.SetLanguage((Language)0, "InLevel");
				Misc.SetLanguage((Language)1, "杂项");
				Misc.SetLanguage((Language)0, "Misc");
				Enemy.SetLanguage((Language)1, "敌人");
				Enemy.SetLanguage((Language)0, "Enemy");
				Security.SetLanguage((Language)1, "安全");
				Security.SetLanguage((Language)0, "Security");
			}
		}

		public static EntryPoint Instance { get; private set; }

		public bool ApplyHarmonyPatches => false;

		public bool UsesLegacyPatches => false;

		public ArchiveLegacyPatcher Patcher { get; set; }

		public string ModuleGroup => FeatureGroup.op_Implicit(Groups.ModuleGroup);

		public Dictionary<Language, string> ModuleGroupLanguages => new Dictionary<Language, string>
		{
			{
				(Language)1,
				"管理系统"
			},
			{
				(Language)0,
				"Admin System"
			}
		};

		public override void Load()
		{
			Instance = this;
			ArchiveMod.RegisterArchiveModule(typeof(EntryPoint));
			Logs.LogMessage("OK");
		}

		public override bool Unload()
		{
			ArchiveMod.UnpatchModule((IArchiveModule)(object)Instance);
			return ((BasePlugin)this).Unload();
		}

		public void Init()
		{
		}

		public void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
		}

		public void OnLateUpdate()
		{
		}

		public void OnExit()
		{
		}
	}
	public static class PluginInfo
	{
		public const string GUID = "Hikaria.AdminSystem";

		public const string NAME = "AdminSystem";

		public const string VERSION = "3.1.1";

		public const int INTERNAL_VERSION = 10475;

		public const string AUTHOR = "Tuesday";
	}
}
namespace Hikaria.AdminSystem.Utilities
{
	public static class AdminUtils
	{
		public static LocalPlayerAgent LocalPlayerAgent => ((Il2CppObjectBase)PlayerManager.GetLocalPlayerAgent()).TryCast<LocalPlayerAgent>();

		public static bool TryGetPlayerAgentFromSlotIndex(int slot, out PlayerAgent player)
		{
			slot--;
			if (!PlayerManager.TryGetPlayerAgent(ref slot, ref player))
			{
				return false;
			}
			return true;
		}

		public static T CopyProperties<T>(T source, T target)
		{
			PropertyInfo[] properties = source.GetType().GetProperties();
			foreach (PropertyInfo sourceProp in properties)
			{
				if (target.GetType().GetProperties().Any((PropertyInfo targetProp) => targetProp.Name == sourceProp.Name && targetProp.GetType() == sourceProp.GetType() && targetProp.CanWrite))
				{
					object value = sourceProp.GetValue(source);
					PropertyInfo property = target.GetType().GetProperty(sourceProp.Name);
					if (property.PropertyType != typeof(Il2CppObjectBase) || property.PropertyType != typeof(Object))
					{
						property.SetValue(target, value);
					}
				}
			}
			return target;
		}
	}
	internal static class Logs
	{
		private static IArchiveLogger _logger;

		private static IArchiveLogger Logger => _logger ?? (_logger = LoaderWrapper.CreateLoggerInstance("Hikaria.AdminSystem", ConsoleColor.White));

		public static void LogDebug(object data)
		{
			Logger.Debug(data.ToString());
		}

		public static void LogError(object data)
		{
			Logger.Error(data.ToString());
		}

		public static void LogInfo(object data)
		{
			Logger.Info(data.ToString());
		}

		public static void LogMessage(object data)
		{
			Logger.Msg(ConsoleColor.White, data.ToString());
		}

		public static void LogWarning(object data)
		{
			Logger.Warning(data.ToString());
		}

		public static void LogNotice(object data)
		{
			Logger.Notice(data.ToString());
		}

		public static void LogSuccess(object data)
		{
			Logger.Success(data.ToString());
		}

		public static void LogException(Exception ex)
		{
			Logger.Exception(ex);
		}
	}
}
namespace Hikaria.AdminSystem.Managers
{
	public class EnemyDataManager : InitSingletonBase<TranslateManager>, IInitAfterGameDataInitialized, IInitializable
	{
		public struct EnemyDamageData
		{
			public uint Id { get; set; }

			public bool IsImmortal { get; set; }

			public Dictionary<int, float> Weakspots { get; set; }

			public Dictionary<int, float> Normalspots { get; set; }

			public Dictionary<int, float> Armorspots { get; set; }

			public Dictionary<int, float> RealArmorSpots { get; set; }

			public bool HasWeakSpot => Weakspots.Count > 0;

			public bool HasNormalSpot => Normalspots.Count > 0;

			public bool HasArmorSpot => Armorspots.Count > 0;

			public bool HasRealArmorSpot => RealArmorSpots.Count > 0;

			public EnemyDamageData()
			{
				Id = 0u;
				IsImmortal = false;
				Weakspots = new Dictionary<int, float>();
				Normalspots = new Dictionary<int, float>();
				Armorspots = new Dictionary<int, float>();
				RealArmorSpots = new Dictionary<int, float>();
			}
		}

		public static Dictionary<uint, EnemyDataBlock> EnemyDataBlockLookup { get; set; } = new Dictionary<uint, EnemyDataBlock>();


		public static Dictionary<uint, EnemyDamageData> EnemyDamageDataLookup { get; set; } = new Dictionary<uint, EnemyDamageData>();


		public static float ArmorMultiThreshold { get; set; } = 0.1f;


		public void Init()
		{
			EnemyDataBlockLookup.Clear();
			foreach (EnemyDataBlock item in GameDataBlockBase<EnemyDataBlock>.GetAllBlocksForEditor())
			{
				EnemyDataBlockLookup.Add(((GameDataBlockBase<EnemyDataBlock>)(object)item).persistentID, item);
			}
		}

		public static EnemyDamageData GetOrGenerateEnemyDamageData(EnemyAgent enemy)
		{
			if (!EnemyDamageDataLookup.TryGetValue(enemy.EnemyDataID, out var value))
			{
				return GenerateAndStoreEnemyDamageData(enemy);
			}
			return value;
		}

		private static EnemyDamageData GenerateAndStoreEnemyDamageData(EnemyAgent enemy)
		{
			//IL_0032: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected I4, but got Unknown
			EnemyDamageData enemyDamageData = new EnemyDamageData();
			enemyDamageData.Id = enemy.EnemyDataID;
			foreach (Dam_EnemyDamageLimb item in (Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)enemy.Damage.DamageLimbs)
			{
				eLimbDamageType type = item.m_type;
				switch ((int)type)
				{
				case 2:
					if (item.m_armorDamageMulti < ArmorMultiThreshold)
					{
						enemyDamageData.RealArmorSpots.Add(item.m_limbID, item.m_armorDamageMulti);
					}
					else
					{
						enemyDamageData.Armorspots.Add(item.m_limbID, item.m_armorDamageMulti);
					}
					break;
				case 1:
					enemyDamageData.Weakspots.Add(item.m_limbID, item.m_weakspotDamageMulti);
					break;
				case 0:
					enemyDamageData.Normalspots.Add(item.m_limbID, 1f);
					break;
				}
			}
			enemyDamageData.Armorspots = enemyDamageData.Armorspots.OrderByDescending((KeyValuePair<int, float> p) => p.Value).ToDictionary((KeyValuePair<int, float> p) => p.Key, (KeyValuePair<int, float> p) => p.Value);
			enemyDamageData.Weakspots = enemyDamageData.Weakspots.OrderByDescending((KeyValuePair<int, float> p) => p.Value).ToDictionary((KeyValuePair<int, float> p) => p.Key, (KeyValuePair<int, float> p) => p.Value);
			enemyDamageData.IsImmortal = enemyDamageData.RealArmorSpots.Count == ((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)enemy.Damage.DamageLimbs).Count;
			EnemyDamageDataLookup.Add(enemy.EnemyDataID, enemyDamageData);
			return enemyDamageData;
		}

		public static void ClearGeneratedEnemyDamageData()
		{
			EnemyDamageDataLookup.Clear();
		}
	}
	[HideInModSettings]
	[EnableFeatureByDefault]
	[DoNotSaveToConfig]
	[DisallowInGameToggle]
	public class GameEventManager : Feature
	{
		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class SNet_GlobalManager__Setup__Patch
		{
			private static void Postfix()
			{
				SNet_Events.OnPlayerEvent += Action<SNet_Player, SNet_PlayerEvent, SNet_PlayerEventReason>.op_Implicit((Action<SNet_Player, SNet_PlayerEvent, SNet_PlayerEventReason>)OnPlayerEvent);
				SNet_Events.OnRecallComplete += Action<eBufferType>.op_Implicit((Action<eBufferType>)OnRecallComplete);
			}
		}

		private static readonly HashSet<IOnPlayerEvent> _instancesOnPlayerEvent = new HashSet<IOnPlayerEvent>();

		private static readonly HashSet<IOnSessionMemberChanged> _instancesSessionMemberChanged = new HashSet<IOnSessionMemberChanged>();

		private static readonly HashSet<IOnAfterLevel> _instancesOnAfterLevel = new HashSet<IOnAfterLevel>();

		private static readonly HashSet<IOnRecallComplete> _instancesOnRecallDone = new HashSet<IOnRecallComplete>();

		public override string Name => "游戏事件监听";

		public static IArchiveLogger FeatureLogger { get; set; }

		private static void OnPlayerEvent(SNet_Player player, SNet_PlayerEvent playerEvent, SNet_PlayerEventReason reason)
		{
			//IL_0034: 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_0039: Invalid comparison between Unknown and I4
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_003d: Invalid comparison between Unknown and I4
			foreach (IOnPlayerEvent item in _instancesOnPlayerEvent)
			{
				try
				{
					item.OnPlayerEvent(player, playerEvent, reason);
				}
				catch (Exception ex)
				{
					FeatureLogger.Error(ex.ToString());
				}
				try
				{
					if ((int)playerEvent == 0)
					{
						goto IL_003f;
					}
					if ((int)playerEvent != 5)
					{
						if ((int)playerEvent == 6)
						{
							goto IL_003f;
						}
					}
					else
					{
						OnSessionMemberChanged(player, SessionMemberEvent.JoinSessionHub);
					}
					goto end_IL_0034;
					IL_003f:
					OnSessionMemberChanged(player, SessionMemberEvent.LeftSessionHub);
					end_IL_0034:;
				}
				catch (Exception ex2)
				{
					FeatureLogger.Error(ex2.ToString());
				}
			}
		}

		private static void OnSessionMemberChanged(SNet_Player player, SessionMemberEvent playerEvent)
		{
			FeatureLogger.Msg(ConsoleColor.White, $"{player.NickName} [{player.Lookup}] {playerEvent}");
			foreach (IOnSessionMemberChanged item in _instancesSessionMemberChanged)
			{
				try
				{
					item.OnSessionMemberChanged(player, playerEvent);
				}
				catch (Exception ex)
				{
					FeatureLogger.Error(ex.ToString());
				}
			}
		}

		private static void OnRecallComplete(eBufferType bufferType)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			foreach (IOnRecallComplete item in _instancesOnRecallDone)
			{
				try
				{
					item.OnRecallComplete(bufferType);
				}
				catch (Exception ex)
				{
					FeatureLogger.Error(ex.ToString());
				}
			}
		}

		private static void OnAfterLevel()
		{
			foreach (IOnAfterLevel item in _instancesOnAfterLevel)
			{
				try
				{
					item.OnAfterLevel();
				}
				catch (Exception ex)
				{
					FeatureLogger.Error(ex.ToString());
				}
			}
		}

		public override void OnGameStateChanged(int state)
		{
			if (state == 11)
			{
				OnAfterLevel();
			}
		}

		public static void RegisterSelfInGameEventManager<T>(T instance)
		{
			Type typeFromHandle = typeof(T);
			if (!typeFromHandle.IsInterface && !typeFromHandle.IsAbstract)
			{
				if (typeof(IOnPlayerEvent).IsAssignableFrom(typeFromHandle))
				{
					_instancesOnPlayerEvent.Add((IOnPlayerEvent)(object)instance);
				}
				if (typeof(IOnSessionMemberChanged).IsAssignableFrom(typeFromHandle))
				{
					_instancesSessionMemberChanged.Add((IOnSessionMemberChanged)(object)instance);
				}
				if (typeof(IOnAfterLevel).IsAssignableFrom(typeFromHandle))
				{
					_instancesOnAfterLevel.Add((IOnAfterLevel)(object)instance);
				}
				if (typeof(IOnRecallComplete).IsAssignableFrom(typeFromHandle))
				{
					_instancesOnRecallDone.Add((IOnRecallComplete)(object)instance);
				}
			}
		}
	}
	public class PauseManager : MonoBehaviour
	{
		private Coroutine _PauseUpdateCoroutine;

		public static PauseManager Current;

		private List<IPauseable> _PausableUpdaters = new List<IPauseable>();

		private static bool s_isPaused;

		private static GameObject s_Object;

		public static bool IsPaused
		{
			get
			{
				return s_isPaused;
			}
			set
			{
				if (s_isPaused != value)
				{
					s_isPaused = value;
					if (value)
					{
						Current.SetPaused();
						PauseManager.IsPaused = true;
					}
					else
					{
						Current.SetUnpaused();
						PauseManager.IsPaused = false;
					}
				}
			}
		}

		public static float PauseUpdateInterval => Time.fixedDeltaTime;

		public static void Setup()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if ((Object)(object)s_Object == (Object)null)
			{
				ClassInjector.RegisterTypeInIl2Cpp<PauseManager>(false);
				s_Object = new GameObject(typeof(PauseManager).FullName);
				Object.DontDestroyOnLoad((Object)(object)s_Object);
				s_Object.AddComponent<PauseManager>();
			}
		}

		private void Awake()
		{
			Current = this;
		}

		private void SetPaused()
		{
			if (SNet.IsMaster)
			{
				SNet.Capture.CaptureGameState((eBufferType)4);
			}
			if (_PauseUpdateCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_PauseUpdateCoroutine);
			}
			_PauseUpdateCoroutine = MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, UpdateRegistered());
			foreach (IPauseable pausableUpdater in _PausableUpdaters)
			{
				pausableUpdater.OnPaused();
			}
		}

		private void SetUnpaused()
		{
			if (_PauseUpdateCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_PauseUpdateCoroutine);
				_PauseUpdateCoroutine = null;
			}
			foreach (IPauseable pausableUpdater in _PausableUpdaters)
			{
				pausableUpdater.OnUnpaused();
			}
			if (SNet.IsMaster)
			{
				SNet.Sync.StartRecallWithAllSyncedPlayers((eBufferType)4, false);
			}
		}

		private IEnumerator UpdateRegistered()
		{
			WaitForSecondsRealtime yielder = new WaitForSecondsRealtime(PauseUpdateInterval);
			while (true)
			{
				foreach (IPauseable pausableUpdater in _PausableUpdaters)
				{
					pausableUpdater.PausedUpdate();
				}
				yield return yielder;
			}
		}

		public void RegisterForPausedUpdate(IPauseable pu)
		{
			_PausableUpdaters.Add(pu);
		}

		public void UnregisterPausedUpdate(IPauseable pu)
		{
			_PausableUpdaters.Remove(pu);
		}
	}
	public class TranslateManager
	{
		public class EnemyIDNameData
		{
			public List<uint> IDs { get; set; }

			public string Name { get; set; }
		}

		public struct EnemyIDName
		{
			public List<uint> IDs { get; set; }

			public string Name { get; set; }
		}

		private static Dictionary<uint, string> EnemyID2NameLookup = new Dictionary<uint, string>();

		private static CustomSetting<List<EnemyIDNameData>> EnemyIDNames = new CustomSetting<List<EnemyIDNameData>>("EnemyIDNameLookup", new List<EnemyIDNameData>(), (Action<List<EnemyIDNameData>>)delegate(List<EnemyIDNameData> data)
		{
			EnemyID2NameLookup.Clear();
			foreach (EnemyIDNameData datum in data)
			{
				foreach (uint iD in datum.IDs)
				{
					EnemyID2NameLookup.TryAdd(iD, datum.Name);
				}
			}
		}, (LoadingTime)1, true);

		private static Dictionary<string, uint[]> EnemyName2ID = new Dictionary<string, uint[]>();

		public static string EnemyName(uint id)
		{
			if (!EnemyID2NameLookup.TryGetValue(id, out var value))
			{
				return $"{((GameDataBlockBase<EnemyDataBlock>)(object)GameDataBlockBase<EnemyDataBlock>.GetBlock(id)).name} [{id}]";
			}
			return value;
		}
	}
}
namespace Hikaria.AdminSystem.Interfaces
{
	public interface IOnAfterLevel
	{
		void OnAfterLevel();
	}
	public interface IOnPlayerEvent
	{
		void OnPlayerEvent(SNet_Player player, SNet_PlayerEvent playerEvent, SNet_PlayerEventReason reason);
	}
	public interface IOnRecallComplete
	{
		void OnRecallComplete(eBufferType bufferType);
	}
	public interface IOnSessionMemberChanged
	{
		void OnSessionMemberChanged(SNet_Player player, SessionMemberEvent playerEvent);
	}
	public enum SessionMemberEvent
	{
		JoinSessionHub,
		LeftSessionHub
	}
	public interface IPauseable
	{
		void PausedUpdate();

		void OnPaused();

		void OnUnpaused();
	}
}
namespace Hikaria.AdminSystem.Features.Weapon
{
	public class BurstLikeGluegun : Feature
	{
		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class BWA_Burst__Update__Patch
		{
			private static bool Prefix(BWA_Burst __instance)
			{
				Update(__instance);
				return false;
			}
		}

		public override string Name => "胶枪式连发武器蓄力开火";

		public override FeatureGroup Group => EntryPoint.Groups.Weapon;

		public static void Update(BWA_Burst __instance)
		{
			//IL_0058: 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: Invalid comparison between Unknown and I4
			if ((Object)(object)((BulletWeaponArchetype)__instance).m_owner == (Object)null)
			{
				return;
			}
			bool flag = !((BulletWeaponArchetype)__instance).m_owner.Locomotion.IsRunning && !((BulletWeaponArchetype)__instance).m_owner.Locomotion.IsInAir;
			((BulletWeaponArchetype)__instance).m_fireHeld = flag && (((ItemEquippable)((BulletWeaponArchetype)__instance).m_weapon).FireButton || (InputMapper.HasGamepad && InputMapper.GetAxisKeyMouseGamepad((InputAction)47, ((BulletWeaponArchetype)__instance).m_owner.InputFilter) > 0f));
			if (flag && ((ItemEquippable)((BulletWeaponArchetype)__instance).m_weapon).FireButtonPressed)
			{
				((BulletWeaponArchetype)__instance).m_firePressed = true;
			}
			else if (((BulletWeaponArchetype)__instance).m_fireHeld && ((BulletWeaponArchetype)__instance).m_firePressed)
			{
				((BulletWeaponArchetype)__instance).m_firePressed = false;
			}
			if (((ItemEquippable)((BulletWeaponArchetype)__instance).m_weapon).IsEnabled || (((BulletWeaponArchetype)__instance).m_owner.FPItemHolder.ItemDownTrigger && (int)((BulletWeaponArchetype)__instance).m_archetypeData.FireMode == 1 && !((BulletWeaponArchetype)__instance).BurstIsDone()))
			{
				((BulletWeaponArchetype)__instance).m_clip = ((ItemEquippable)((BulletWeaponArchetype)__instance).m_weapon).GetCurrentClip();
				bool flag2 = (((((BulletWeaponArchetype)__instance).HasChargeup && ((BulletWeaponArchetype)__instance).m_inChargeup) || !((BulletWeaponArchetype)__instance).m_triggerNeedsPress) ? ((BulletWeaponArchetype)__instance).m_fireHeld : ((BulletWeaponArchetype)__instance).m_firePressed);
				if (!((BulletWeaponArchetype)__instance).m_inChargeup && !((BulletWeaponArchetype)__instance).m_firing && flag2 && Clock.Time > ((BulletWeaponArchetype)__instance).m_nextBurstTimer)
				{
					if (((BulletWeaponArchetype)__instance).m_clip > 0f)
					{
						if (((BulletWeaponArchetype)__instance).HasChargeup)
						{
							((BulletWeaponArchetype)__instance).m_chargeupTimer = Clock.Time + ((BulletWeaponArchetype)__instance).ChargeupDelay();
							((BulletWeaponArchetype)__instance).m_inChargeup = true;
							((BulletWeaponArchetype)__instance).m_readyToFire = false;
							((BulletWeaponArchetype)__instance).m_weapon.TriggerAudioChargeup();
							((ItemEquippable)((BulletWeaponArchetype)__instance).m_weapon).FPItemHolder.DontRelax();
							GuiManager.CrosshairLayer.SetChargeUpVisibleAndProgress(true, 0f);
						}
						else
						{
							((BulletWeaponArchetype)__instance).m_chargeupTimer = 0f;
							((BulletWeaponArchetype)__instance).m_inChargeup = false;
							GuiManager.CrosshairLayer.SetChargeUpVisibleAndProgress(false, 0f);
							((BulletWeaponArchetype)__instance).m_readyToFire = true;
						}
					}
					else if (((BulletWeaponArchetype)__instance).m_firePressed)
					{
						if (!((BulletWeaponArchetype)__instance).m_clickTriggered || !CellSettingsManager.SettingsData.Gameplay.AutoReload.Value || !((PlayerInventoryBase)((Weapon)((BulletWeaponArchetype)__instance).m_weapon).m_inventory).CanReloadCurrent())
						{
							((BulletWeaponArchetype)__instance).m_weapon.TriggerAudio(((ItemEquippable)((BulletWeaponArchetype)__instance).m_weapon).AudioData.eventClick);
							((BulletWeaponArchetype)__instance).m_nextShotTimer = Clock.Time + ((BulletWeaponArchetype)__instance).ShotDelay();
							((BulletWeaponArchetype)__instance).m_clickTriggered = true;
						}
						else if (((BulletWeaponArchetype)__instance).m_clickTriggered && CellSettingsManager.SettingsData.Gameplay.AutoReload.Value && ((PlayerInventoryBase)((Weapon)((BulletWeaponArchetype)__instance).m_weapon).m_inventory).CanReloadCurrent())
						{
							((PlayerInventoryBase)((Weapon)((BulletWeaponArchetype)__instance).m_weapon).m_inventory).TriggerReload();
							((BulletWeaponArchetype)__instance).m_clickTriggered = false;
						}
						if (((BulletWeaponArchetype)__instance).m_clip <= 0f && !((PlayerInventoryBase)((Weapon)((BulletWeaponArchetype)__instance).m_weapon).m_inventory).CanReloadCurrent())
						{
							((Weapon)((BulletWeaponArchetype)__instance).m_weapon).m_wasOutOfAmmo = true;
						}
					}
					if (((BulletWeaponArchetype)__instance).m_firePressed)
					{
						((BulletWeaponArchetype)__instance).m_firePressed = false;
					}
				}
				if (((BulletWeaponArchetype)__instance).m_inChargeup)
				{
					if (!((BulletWeaponArchetype)__instance).m_fireHeld)
					{
						int num = Mathf.FloorToInt(Mathf.Clamp01(1f - (((BulletWeaponArchetype)__instance).m_chargeupTimer - Clock.Time) / ((BulletWeaponArchetype)__instance).ChargeupDelay()) * (float)__instance.m_burstMax);
						if (num == 0 || num == __instance.m_burstMax)
						{
							((BulletWeaponArchetype)__instance).OnStopChargeup();
							((BulletWeaponArchetype)__instance).m_nextShotTimer = Clock.Time + ((BulletWeaponArchetype)__instance).ShotDelay();
							return;
						}
						((BulletWeaponArchetype)__instance).m_inChargeup = false;
						((BulletWeaponArchetype)__instance).m_readyToFire = true;
						GuiManager.CrosshairLayer.SetChargeUpVisibleAndProgress(false, 0f);
						OnStartFiring(__instance, num);
						goto IL_03c3;
					}
					float num2 = 1f - (((BulletWeaponArchetype)__instance).m_chargeupTimer - Clock.Time) / ((BulletWeaponArchetype)__instance).ChargeupDelay();
					GuiManager.CrosshairLayer.SetChargeUpVisibleAndProgress(true, num2);
					if (Clock.Time >= ((BulletWeaponArchetype)__instance).m_chargeupTimer)
					{
						((BulletWeaponArchetype)__instance).m_inChargeup = false;
						((BulletWeaponArchetype)__instance).m_readyToFire = true;
						GuiManager.CrosshairLayer.SetChargeUpVisibleAndProgress(false, 0f);
					}
				}
				if (((BulletWeaponArchetype)__instance).m_readyToFire && !((BulletWeaponArchetype)__instance).m_firing)
				{
					((BulletWeaponArchetype)__instance).OnStartFiring();
				}
				goto IL_03c3;
			}
			if (((BulletWeaponArchetype)__instance).m_inChargeup)
			{
				((BulletWeaponArchetype)__instance).OnStopChargeup();
			}
			if (((BulletWeaponArchetype)__instance).m_firing)
			{
				((BulletWeaponArchetype)__instance).OnStopFiring();
			}
			return;
			IL_03c3:
			if (((BulletWeaponArchetype)__instance).PreFireCheck())
			{
				if (((BulletWeaponArchetype)__instance).m_readyToFire && ((BulletWeaponArchetype)__instance).m_firing && Clock.Time > ((BulletWeaponArchetype)__instance).m_nextShotTimer)
				{
					if (((BulletWeaponArchetype)__instance).m_clip > 0f)
					{
						((BulletWeaponArchetype)__instance).OnFireShot();
						((BulletWeaponArchetype)__instance).m_nextShotTimer = Clock.Time + ((BulletWeaponArchetype)__instance).ShotDelay();
					}
					else
					{
						((BulletWeaponArchetype)__instance).OnStopFiring();
						((BulletWeaponArchetype)__instance).OnFireShotEmptyClip();
						((BulletWeaponArchetype)__instance).m_nextShotTimer = Clock.Time + ((BulletWeaponArchetype)__instance).ShotDelay();
					}
					((BulletWeaponArchetype)__instance).PostFireCheck();
				}
			}
			else if (((BulletWeaponArchetype)__instance).m_firing)
			{
				((BulletWeaponArchetype)__instance).OnStopFiring();
			}
		}

		public static void OnStartFiring(BWA_Burst __instance, int count)
		{
			((BulletWeaponArchetype)__instance).OnStartFiring();
			int currentClip = ((ItemEquippable)((BulletWeaponArchetype)__instance).m_weapon).GetCurrentClip();
			__instance.m_burstCurrentCount = Mathf.Min(__instance.m_burstMax, Mathf.Min(count, currentClip));
			if (currentClip >= __instance.m_burstMax && !((ItemEquippable)((BulletWeaponArchetype)__instance).m_weapon).AudioData.TriggerBurstAudioForEachShot)
			{
				((BulletWeaponArchetype)__instance).m_weapon.TriggerBurstFireAudio();
				((ItemEquippable)((BulletWeaponArchetype)__instance).m_weapon).FPItemHolder.DontRelax();
			}
		}
	}
	[EnableFeatureByDefault]
	[DisallowInGameToggle]
	[DoNotSaveToConfig]
	public class InfiniteClip : Feature
	{
		public class InfiniteClipSettings
		{
			[FSDisplayName("无限弹夹容量")]
			public bool EnableInfiniteClip { get; set; }
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private static class BulletWeapon_Fire_Patch
		{
			private static void Postfix(BulletWeapon __instance)
			{
				if (!Object.op_Implicit((Object)(object)((Item)__instance).Owner) != Object.op_Implicit((Object)(object)AdminUtils.LocalPlayerAgent) && Settings.EnableInfiniteClip)
				{
					__instance.m_clip = ((ItemEquippable)__instance).GetMaxClip();
					__instance.UpdateAmmoStatus();
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private static class Shotgun_Fire_Patch
		{
			private static void Postfix(Shotgun __instance)
			{
				if (!Object.op_Implicit((Object)(object)((Item)__instance).Owner) != Object.op_Implicit((Object)(object)AdminUtils.LocalPlayerAgent) && Settings.EnableInfiniteClip)
				{
					((BulletWeapon)__instance).m_clip = ((ItemEquippable)__instance).ClipSize;
					((BulletWeapon)__instance).UpdateAmmoStatus();
				}
			}
		}

		public override string Name => "无限弹夹容量";

		public override string Description => "射击时枪械弹夹容量始终为满";

		public override FeatureGroup Group => EntryPoint.Groups.Weapon;

		[FeatureConfig]
		public static InfiniteClipSettings Settings { get; set; }

		public override void Init()
		{
			DevConsole.AddCommand(Command.Create<bool?>("InfClip", "无限弹夹容量", "无限弹夹容量", Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<bool?>)delegate(bool? enable)
			{
				if (!enable.HasValue)
				{
					enable = !Settings.EnableInfiniteClip;
				}
				Settings.EnableInfiniteClip = enable.Value;
				DevConsole.LogSuccess((object)("已" + (enable.Value ? "启用" : "禁用") + " 无限弹夹容量"));
			}, (Action)delegate
			{
				DevConsole.LogVariable("无限弹夹容量", (object)Settings.EnableInfiniteClip, "");
			}), false);
		}
	}
	[EnableFeatureByDefault]
	[DisallowInGameToggle]
	[DoNotSaveToConfig]
	public class WeaponAutoAim : Feature
	{
		public class WeaponAutoAimSettings
		{
			[Localized]
			public enum AutoAimMode
			{
				Crosshair,
				Closest
			}

			[Localized]
			public enum AutoFireMode
			{
				Off,
				SemiAuto,
				FullyAuto
			}

			[FSDisplayName("启用自瞄")]
			public bool EnableAutoAim { get; set; }

			[FSDisplayName("隔墙自瞄")]
			public bool WallHackAim { get; set; }

			[FSDisplayName("自瞄节点距离")]
			[FSDescription("默认为3个节点")]
			public int AutoAimNodeRange { get; set; } = 3;


			[FSDisplayName("自瞄模式")]
			[FSDescription("准心优先 或 近处优先")]
			public AutoAimMode AimMode { get; set; }

			[FSDisplayName("暂停自瞄按键")]
			[FSDescription("按下后可暂停自瞄,松开后恢复")]
			public KeyCode PauseAutoAimKey { get; set; } = (KeyCode)304;


			[FSDisplayName("自动开火模式")]
			public AutoFireMode AutoFire { get; set; }

			[FSDisplayName("自瞄范围半径")]
			[FSDescription("单位: 像素")]
			public float AimRange { get; set; } = 720f;


			[FSDisplayName("自瞄范围角度")]
			[FSDescription("默认为90度")]
			public float AimAngle { get; set; } = 90f;


			[FSDisplayName("装甲部位检测阈值")]
			[FSDescription("默认值为0.1")]
			public float ArmorLimbDamageMultiThreshold
			{
				get
				{
					return EnemyDataManager.ArmorMultiThreshold;
				}
				set
				{
					EnemyDataManager.ArmorMultiThreshold = value;
					EnemyDataManager.ClearGeneratedEnemyDamageData();
				}
			}

			[FSHeader("颜色设置", true)]
			[FSDisplayName("目标通用颜色")]
			public SColor TargetedColor { get; set; } = new SColor(1.2f, 0.3f, 0.1f, (float?)1f);


			[FSDisplayName("目标弱点颜色")]
			public SColor TargetedWeakspotColor { get; set; } = new SColor(1.2f, 0.6f, 0f, (float?)1f);


			[FSDisplayName("无目标颜色")]
			public SColor UnTargetedColor { get; set; } = new SColor(0.3f, 0.1f, 0.1f, (float?)1f);


			[FSDisplayName("非活跃颜色")]
			public SColor PassiveDetection { get; set; } = new SColor(0.5f, 0.5f, 0.5f, (float?)0.5f);

		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class BulletWeapon__OnWield__Patch
		{
			private static void Postfix(BulletWeapon __instance)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Invalid comparison between Unknown and I4
				if ((int)GameStateManager.Current.m_currentStateName == 10 && IsWeaponOwner(__instance))
				{
					WeaponAutoAimHandler weaponAutoAimHandler = ((Component)__instance).gameObject.GetComponent<WeaponAutoAimHandler>();
					if ((Object)(object)weaponAutoAimHandler == (Object)null)
					{
						weaponAutoAimHandler = ((Component)__instance).gameObject.AddComponent<WeaponAutoAimHandler>();
					}
					weaponAutoAimHandler.Setup(__instance, ((Item)__instance).Owner, ((Item)__instance).Owner.FPSCamera);
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		public class BulletWeapon__OnUnWield__Patch
		{
			private static void Prefix(BulletWeapon __instance)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Invalid comparison between Unknown and I4
				if ((int)GameStateManager.Current.m_currentStateName == 10 && IsWeaponOwner(__instance))
				{
					WeaponAutoAimHandler component = ((Component)__instance).gameObject.GetComponent<WeaponAutoAimHandler>();
					if (!((Object)(object)component == (Object)null))
					{
						component.DoClear();
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		public class PlayerEnemyCollision__FindNearbyEnemiesMovementReduction__Patch
		{
			private static bool Prefix(PlayerEnemyCollision __instance, Vector3 pos, ref float __result)
			{
				//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_005b: 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)
				float num = 1f;
				if (((Agent)__instance.m_owner).CourseNode == null)
				{
					__result = num;
					return false;
				}
				__instance.m_enemies.Clear();
				AIG_CourseNode.GetEnemiesInNodes(((Agent)__instance.m_owner).CourseNode, Settings.AutoAimNodeRange, __instance.m_enemies);
				for (int i = 0; i < __instance.m_enemies.Count; i++)
				{
					EnemyAgent val = __instance.m_enemies[i];
					Vector3 val2 = val.Position - pos;
					if (((Agent)val).Alive && ((Vector3)(ref val2)).magnitude < val.EnemyBalancingData.EnemyCollisionRadius)
					{
						float enemyCollisionPlayerMovementReduction = val.EnemyBalancingData.EnemyCollisionPlayerMovementReduction;
						float num2 = num - enemyCollisionPlayerMovementReduction;
						float enemyCollisionMinimumMoveSpeedModifier = val.EnemyBalancingData.EnemyCollisionMinimumMoveSpeedModifier;
						num = Mathf.Min(num, Mathf.Max(num2, enemyCollisionMinimumMoveSpeedModifier));
					}
				}
				__result = num;
				return false;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		public class Weapon__CastWeaponRay__Patch
		{
			public static Type[] ParameterTypes()
			{
				return new Type[4]
				{
					typeof(Transform),
					typeof(WeaponHitData).MakeByRefType(),
					typeof(Vector3),
					typeof(int)
				};
			}

			private static void Prefix(ref WeaponHitData weaponRayData)
			{
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)weaponRayData.owner == (Object)null || (Object)(object)weaponRayData.owner.Owner == (Object)null || !weaponRayData.owner.Owner.IsLocal)
				{
					return;
				}
				ArchetypeDataBlock archetypeData = weaponRayData.owner.Inventory.WieldedItem.ArchetypeData;
				if (archetypeData == null)
				{
					return;
				}
				if (!WeaponAutoAimHandler.TryGetInstance(((GameDataBlockBase<ArchetypeDataBlock>)(object)archetypeData).persistentID, out var weaponAutoAim))
				{
					weaponAutoAim = ((Component)weaponRayData.owner.Inventory.WieldedItem).GetComponent<WeaponAutoAimHandler>();
					if ((Object)(object)weaponAutoAim == (Object)null)
					{
						return;
					}
					WeaponAutoAimHandler.Register(((GameDataBlockBase<ArchetypeDataBlock>)(object)archetypeData).persistentID, weaponAutoAim);
				}
				if (weaponAutoAim.HasTarget && (InputMapper.GetButtonKeyMouse((InputAction)7, (eFocusState)4) || Settings.AutoFire == WeaponAutoAimSettings.AutoFireMode.FullyAuto))
				{
					weaponRayData.maxRayDist = 2000f;
					WeaponHitData obj = weaponRayData;
					Vector3 val = weaponAutoAim.AimTargetPos - weaponRayData.owner.FPSCamera.Position;
					obj.fireDir = ((Vector3)(ref val)).normalized;
				}
			}
		}

		public class WeaponAutoAimHandler : MonoBehaviour
		{
			private GameObject m_ReticleHolder;

			private CrosshairHitIndicator m_Reticle;

			private EnemyAgent m_Target;

			private Dam_EnemyDamageLimb m_TargetLimb;

			private Camera m_PlayerCamera;

			private bool m_HasTarget;

			private BulletWeapon m_BulletWeapon;

			private PlayerAgent m_Owner;

			private Vector3 m_TargetedEulerAngles = new Vector3(0f, 0f, 45f);

			private float fireTimer;

			private float updateTick = 0.05f;

			public Vector3 AimTargetPos
			{
				get
				{
					//IL_0017: 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_005b: 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)
					if (!Settings.EnableAutoAim)
					{
						return m_Owner.FPSCamera.CameraRayPos;
					}
					if (HasTarget)
					{
						return m_TargetLimb.DamageTargetPos;
					}
					if ((Object)(object)m_Target != (Object)null)
					{
						return ((Agent)m_Target).AimTarget.position;
					}
					return m_Owner.FPSCamera.CameraRayPos;
				}
			}

			public static WeaponAutoAimHandler Current { get; private set; }

			public List<EnemyAgent> AroundEnemies { get; private set; } = new List<EnemyAgent>();


			public static Dictionary<uint, WeaponAutoAimHandler> AutoAimInstances { get; private set; } = new Dictionary<uint, WeaponAutoAimHandler>();


			public static HashSet<WeaponAutoAimHandler> AllAutoAimInstances { get; private set; } = new HashSet<WeaponAutoAimHandler>();


			internal bool HasTarget
			{
				get
				{
					if ((Object)(object)m_Target != (Object)null && ((Agent)m_Target).Alive)
					{
						return (Object)(object)m_TargetLimb != (Object)null;
					}
					return false;
				}
			}

			private bool PauseAutoAim
			{
				get
				{
					//IL_0005: Unknown result type (might be due to invalid IL or missing references)
					if (Input.GetKey(Settings.PauseAutoAimKey) && ((ItemEquippable)m_BulletWeapon).AimButtonHeld)
					{
						return Settings.AutoFire == WeaponAutoAimSettings.AutoFireMode.Off;
					}
					return false;
				}
			}

			public static void Register(uint persistentID, WeaponAutoAimHandler weaponAutoAim)
			{
				AutoAimInstances.Add(persistentID, weaponAutoAim);
			}

			public static void Unregister(uint persistentID)
			{
				AutoAimInstances.Remove(persistentID);
			}

			public static bool TryGetInstance(uint persistentID, out WeaponAutoAimHandler weaponAutoAim)
			{
				return AutoAimInstances.TryGetValue(persistentID, out weaponAutoAim);
			}

			private void Awake()
			{
				Current = this;
				AllAutoAimInstances.Add(this);
			}

			private void OnDestroy()
			{
				AllAutoAimInstances.Remove(this);
				if ((Object)(object)m_Reticle != (Object)null)
				{
					((GuiLayerComp)m_Reticle).SetVisible(false, false);
				}
				m_HasTarget = false;
				m_Target = null;
				SharedUtils.SafeDestroy((Component)(object)m_Reticle);
				SharedUtils.SafeDestroy(m_ReticleHolder);
			}

			public void Setup(BulletWeapon weapon, PlayerAgent owner, FPSCamera camera)
			{
				if ((Object)(object)m_Owner == (Object)null)
				{
					m_BulletWeapon = weapon;
					m_Owner = owner;
					m_PlayerCamera = ((Component)camera).gameObject.GetComponent<Camera>();
					SetupReticle();
				}
				((Behaviour)this).enabled = Settings.EnableAutoAim;
			}

			public void DoClear()
			{
				if ((Object)(object)m_Reticle != (Object)null)
				{
					CrosshairHitIndicator reticle = m_Reticle;
					if (reticle != null)
					{
						((GuiLayerComp)reticle).SetVisible(false, false);
					}
				}
				m_HasTarget = false;
				m_Target = null;
				Unregister(((GameDataBlockBase<ArchetypeDataBlock>)(object)((ItemEquippable)m_BulletWeapon).ArchetypeData).persistentID);
			}

			public void DoAfterLevelClear()
			{
				DoClear();
				SharedUtils.SafeDestroy((Component)(object)m_Reticle);
				SharedUtils.SafeDestroy(m_ReticleHolder);
				SharedUtils.SafeDestroy((Component)(object)this);
			}

			private void SetupReticle()
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Expected O, but got Unknown
				//IL_0060: 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_007b: 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)
				m_ReticleHolder = new GameObject();
				m_ReticleHolder.transform.SetParent(((GuiLayer)GuiManager.CrosshairLayer).CanvasTrans);
				m_Reticle = Object.Instantiate<CrosshairHitIndicator>(GuiManager.CrosshairLayer.m_hitIndicatorFriendly, m_ReticleHolder.transform);
				((Object)m_Reticle).name = "AutoAimIndicator";
				((Component)m_Reticle).transform.localScale = Vector3.zero;
				SetVFX(SColorExtensions.ToUnityColor(Settings.TargetedColor), m_TargetedEulerAngles);
				((Component)m_Reticle).transform.localEulerAngles = m_TargetedEulerAngles;
			}

			private void Update()
			{
				UpdateColor();
				UpdateTargetEnemy();
				UpdateAutoFire();
			}

			private void UpdateTargetEnemy(bool force = false)
			{
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c6: 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_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: 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_007e: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)m_Target != (Object)null && (Object)(object)m_TargetLimb != (Object)null)
				{
					m_ReticleHolder.transform.position = m_PlayerCamera.WorldToScreenPoint(m_TargetLimb.DamageTargetPos);
					if (!m_HasTarget)
					{
						((Component)m_Reticle).transform.localScale = Vector3.one * 2f;
						((Component)m_Reticle).transform.localEulerAngles = m_TargetedEulerAngles;
						((GuiLayerComp)m_Reticle).AnimateScale(1.5f, 0.13f);
						m_HasTarget = true;
					}
				}
				else
				{
					Transform transform = ((Component)m_Reticle).transform;
					transform.localEulerAngles += new Vector3(0f, 0f, 5f);
				}
				if (m_HasTarget && ((Object)(object)m_Target == (Object)null || (Object)(object)m_TargetLimb == (Object)null))
				{
					((GuiLayerComp)m_Reticle).AnimateScale(0f, 0.5f);
					m_HasTarget = false;
				}
				updateTick += Time.deltaTime;
				if (updateTick >= 0.04f || force)
				{
					UpdateAroundEnemy();
					UpdateBestEnemyTarget();
					UpdateTargetEnemyLimb();
					updateTick = 0f;
				}
			}

			private void UpdateColor()
			{
				//IL_0075: 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_00ae: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0101: 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_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Invalid comparison between Unknown and I4
				//IL_0143: 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_004d: 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_003c: 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_012d: Unknown result type (might be due to invalid IL or missing references)
				if (m_HasTarget && !PauseAutoAim)
				{
					m_Reticle.m_hitColor = (((Object)(object)m_TargetLimb == (Object)null) ? SColorExtensions.ToUnityColor(Settings.UnTargetedColor) : (((int)m_TargetLimb.m_type == 1) ? SColorExtensions.ToUnityColor(Settings.TargetedWeakspotColor) : SColorExtensions.ToUnityColor(Settings.TargetedColor)));
				}
				else
				{
					m_Reticle.m_hitColor = SColorExtensions.ToUnityColor(Settings.UnTargetedColor);
				}
				if (!InputMapper.GetButtonKeyMouse((InputAction)7, (eFocusState)4) || ((ItemEquippable)m_BulletWeapon).GetCurrentClip() <= 0 || PauseAutoAim)
				{
					m_ReticleHolder.transform.localScale = Vector3.one * 0.5f;
					Transform transform = m_ReticleHolder.transform;
					transform.localEulerAngles += new Vector3(0f, 0f, 2f);
					m_Reticle.m_hitColor = SColorExtensions.ToUnityColor(Settings.PassiveDetection);
				}
				else
				{
					m_ReticleHolder.transform.localScale = Vector3.one;
					m_ReticleHolder.transform.localEulerAngles = Vector3.zero;
				}
				m_Reticle.UpdateColorsWithAlphaMul(m_Reticle.m_hitColor.a);
			}

			private void SetVFX(Color color, Vector3 euler)
			{
				//IL_000b: 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)
				((Component)m_Reticle).transform.localEulerAngles = euler;
				m_Reticle.m_hitColor = color;
				m_Reticle.UpdateColorsWithAlphaMul(1f);
			}

			private void UpdateTargetEnemyLimb()
			{
				if ((Object)(object)m_Target == (Object)null || PauseAutoAim)
				{
					return;
				}
				EnemyDataManager.EnemyDamageData orGenerateEnemyDamageData = EnemyDataManager.GetOrGenerateEnemyDamageData(m_Target);
				if (orGenerateEnemyDamageData.IsImmortal)
				{
					if (OneShotKill.OneShotKillLookup.TryGetValue(SNet.LocalPlayer.Lookup, out var value) && value.EnableOneShotKill)
					{
						foreach (KeyValuePair<int, float> armorspot in orGenerateEnemyDamageData.Armorspots)
						{
							Dam_EnemyDamageLimb val = ((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)m_Target.Damage.DamageLimbs)[armorspot.Key];
							if (!val.IsDestroyed && m_Owner.CanFireHitObject(((Component)val).gameObject))
							{
								m_TargetLimb = val;
								return;
							}
						}
					}
					m_TargetLimb = null;
					return;
				}
				if (orGenerateEnemyDamageData.HasWeakSpot)
				{
					foreach (KeyValuePair<int, float> weakspot in orGenerateEnemyDamageData.Weakspots)
					{
						Dam_EnemyDamageLimb val2 = ((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)m_Target.Damage.DamageLimbs)[weakspot.Key];
						if (!val2.IsDestroyed && m_Owner.CanFireHitObject(((Component)val2).gameObject))
						{
							m_TargetLimb = val2;
							return;
						}
					}
				}
				if (orGenerateEnemyDamageData.HasNormalSpot)
				{
					foreach (KeyValuePair<int, float> normalspot in orGenerateEnemyDamageData.Normalspots)
					{
						Dam_EnemyDamageLimb val3 = ((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)m_Target.Damage.DamageLimbs)[normalspot.Key];
						if (!val3.IsDestroyed && m_Owner.CanFireHitObject(((Component)val3).gameObject))
						{
							m_TargetLimb = val3;
							return;
						}
					}
				}
				if (orGenerateEnemyDamageData.HasArmorSpot)
				{
					foreach (KeyValuePair<int, float> armorspot2 in orGenerateEnemyDamageData.Armorspots)
					{
						Dam_EnemyDamageLimb val4 = ((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)m_Target.Damage.DamageLimbs)[armorspot2.Key];
						if (!val4.IsDestroyed && m_Owner.CanFireHitObject(((Component)val4).gameObject))
						{
							m_TargetLimb = val4;
							return;
						}
					}
				}
				if (orGenerateEnemyDamageData.HasRealArmorSpot && OneShotKill.OneShotKillLookup.TryGetValue(SNet.LocalPlayer.Lookup, out var value2) && value2.EnableOneShotKill)
				{
					foreach (KeyValuePair<int, float> realArmorSpot in orGenerateEnemyDamageData.RealArmorSpots)
					{
						Dam_EnemyDamageLimb val5 = ((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)m_Target.Damage.DamageLimbs)[realArmorSpot.Key];
						if (!val5.IsDestroyed && m_Owner.CanFireHitObject(((Component)val5).gameObject))
						{
							m_TargetLimb = val5;
							return;
						}
					}
				}
				m_TargetLimb = null;
			}

			private void UpdateAutoFire(bool force = false)
			{
				if (HasTarget && !PauseAutoAim && ((Settings.AutoFire == WeaponAutoAimSettings.AutoFireMode.SemiAuto && InputMapper.GetButtonKeyMouse((InputAction)7, (eFocusState)4)) || Settings.AutoFire == WeaponAutoAimSettings.AutoFireMode.FullyAuto) && ((ItemEquippable)m_BulletWeapon).GetCurrentClip() > 0)
				{
					fireTimer -= Time.deltaTime;
					if (fireTimer <= 0f || force)
					{
						m_BulletWeapon.Fire(true);
						m_BulletWeapon.TriggerSingleFireAudio();
						fireTimer = ((ItemEquippable)m_BulletWeapon).ArchetypeData.ShotDelay;
					}
				}
				else
				{
					fireTimer = 0f;
				}
			}

			private void UpdateBestEnemyTarget()
			{
				//IL_0074: 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)
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: 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_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_0160: 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)
				if (AroundEnemies == null || AroundEnemies.Count == 0 || PauseAutoAim)
				{
					m_Target = null;
					return;
				}
				EnemyAgent target = null;
				float num = 100000f;
				Vector3 val2 = default(Vector3);
				foreach (EnemyAgent aroundEnemy in AroundEnemies)
				{
					WeaponAutoAimSettings.AutoAimMode aimMode = Settings.AimMode;
					if (aimMode == WeaponAutoAimSettings.AutoAimMode.Crosshair || aimMode != WeaponAutoAimSettings.AutoAimMode.Closest)
					{
						Vector3 val = ((CameraController)m_Owner.FPSCamera).m_camera.WorldToScreenPoint(((Agent)aroundEnemy).AimTarget.position);
						val.z = 0f;
						((Vector3)(ref val2))..ctor((float)(Screen.width / 2), (float)(Screen.height / 2));
						float num2 = Vector3.Distance(val, val2);
						Vector3 val3 = ((Agent)aroundEnemy).AimTarget.position - m_Owner.FPSCamera.Position;
						if (Vector3.Angle(m_Owner.FPSCamera.CameraRayDir, val3) < Settings.AimAngle && num2 <= Settings.AimRange && num2 < num)
						{
							num = num2;
							target = aroundEnemy;
						}
					}
					else
					{
						float num3 = Vector3.Distance(((Agent)aroundEnemy).AimTarget.position, ((Agent)m_Owner).Position);
						Vector3 val4 = ((Agent)aroundEnemy).AimTarget.position - m_Owner.FPSCamera.Position;
						if (Vector3.Angle(m_Owner.FPSCamera.CameraRayDir, val4) < Settings.AimAngle && num3 <= Settings.AimRange && num3 < num)
						{
							num = num3;
							target = aroundEnemy;
						}
					}
				}
				m_Target = target;
			}

			private void UpdateAroundEnemy()
			{
				AroundEnemies.Clear();
				if (PauseAutoAim)
				{
					return;
				}
				Enumerator<EnemyAgent> enumerator = m_Owner.EnemyCollision.m_enemies.GetEnumerator();
				while (enumerator.MoveNext())
				{
					EnemyAgent current = enumerator.Current;
					if ((Settings.WallHackAim || m_Owner.CanSeeEnemyPlus(current)) && ((Agent)current).Alive && ((Dam_SyncedDamageBase)current.Damage).Health > 0f && !current.Damage.IsImortal)
					{
						AroundEnemies.Add(current);
					}
				}
			}
		}

		public override string Name => "自瞄";

		public override string Description => "使用枪械时启用自瞄";

		public override FeatureGroup Group => EntryPoint.Groups.Weapon;

		[FeatureConfig]
		public static WeaponAutoAimSettings Settings { get; set; }

		public override void Init()
		{
			ClassInjector.RegisterTypeInIl2Cpp<WeaponAutoAimHandler>(false);
			DevConsole.AddCommand(Command.Create<bool?>("AutoAim", "自瞄", "自瞄", Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<bool?>)delegate(bool? enable)
			{
				if (!enable.HasValue)
				{
					enable = !Settings.EnableAutoAim;
				}
				Settings.EnableAutoAim = enable.Value;
				DevConsole.LogSuccess((object)("已" + (enable.Value ? "启用" : "禁用") + " 自瞄"));
			}, (Action)delegate
			{
				DevConsole.LogVariable("自瞄", (object)Settings.EnableAutoAim, "");
			}), false);
		}

		public override void OnGameStateChanged(int state)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			eGameStateName val = (eGameStateName)(byte)state;
			if ((int)val != 11 && (int)val != 4 && (int)val != 5 && (int)val != 15)
			{
				return;
			}
			foreach (WeaponAutoAimHandler allAutoAimInstance in WeaponAutoAimHandler.AllAutoAimInstances)
			{
				if ((Object)(object)allAutoAimInstance != (Object)null)
				{
					allAutoAimInstance.DoAfterLevelClear();
				}
			}
		}

		private static bool IsWeaponOwner(BulletWeapon bulletWeapon)
		{
			if ((Object)(object)bulletWeapon == (Object)null || (Object)(object)((Item)bulletWeapon).Owner == (Object)null)
			{
				return false;
			}
			return ((Item)bulletWeapon).Owner.Owner.IsLocal;
		}
	}
	[EnableFeatureByDefault]
	[DisallowInGameToggle]
	[DoNotSaveToConfig]
	internal class WeaponEnhance : Feature
	{
		public class WeaponEnhanceSettings
		{
			private bool _wallHack;

			[FSDisplayName("清晰瞄具")]
			[FSDescription("去除枪械瞄具污渍, 加强热成像瞄具")]
			public bool ClearSight { get; set; }

			[FSDisplayName("无伤害衰减")]
			[FSDescription("枪械伤害没有距离衰减")]
			public bool NoDamageFalloff { get; set; }

			[FSDisplayName("无弹道扩散")]
			[FSDescription("枪械弹道无扩散, 散弹子弹散步减小")]
			public bool NoSpread { get; set; }

			[FSDisplayName("无后座")]
			[FSDescription("枪械无后坐力")]
			public bool NoRecoil { get; set; }

			[FSDisplayName("子弹穿墙")]
			[FSDescription("枪械子弹穿墙")]
			public bool WallHack
			{
				get
				{
					return _wallHack;
				}
				set
				{
					_wallHack = value;
					LayerManager.MASK_BULLETWEAPON_PIERCING_PASS = (_wallHack ? EnemyDamagableLayerMask : BulletPiercingPassMask);
					LayerManager.MASK_BULLETWEAPON_RAY = (_wallHack ? EnemyDamagableLayerMask : BulletWeaponRayMask);
				}
			}

			[FSDisplayName("无声枪")]
			[FSDescription("枪械无开火声音, 即不惊怪(仅客机可用)")]
			public bool SilentWeapon { get; set; }

			[FSDisplayName("自动上弹")]
			[FSDescription("优先消耗后备弹药")]
			public bool AutoReload { get; set; }

			[FSDisplayName("特殊部位伤害溢出")]
			[FSDescription("启用后可以在特殊部位单次打出超过最大生命值上限的伤害")]
			public bool IgnoreLimbMaxHealthClamp { get; set; }
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private static class Dam_EnemyDamageLimb_Custom__ApplyWeakspotAndArmorModifiers__Patch
		{
			private static bool Prefix(Dam_EnemyDamageLimb_Custom __instance, ref float __result, float dam, float precisionMulti = 1f)
			{
				if (!Settings.IgnoreLimbMaxHealthClamp)
				{
					return true;
				}
				__result = dam * Mathf.Max(((Dam_EnemyDamageLimb)__instance).m_weakspotDamageMulti * precisionMulti, 1f) * ((Dam_EnemyDamageLimb)__instance).m_armorDamageMulti;
				return false;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class BulletWeapon__Fire__Patch
		{
			private static void Postfix(BulletWeapon __instance)
			{
				if (Settings.AutoReload && IsWeaponOwner(__instance))
				{
					((PlayerInventoryBase)((Weapon)__instance).m_inventory).DoReload();
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Shotgun__Fire__Patch
		{
			private static void Postfix(Shotgun __instance)
			{
				if (Settings.AutoReload && IsWeaponOwner((BulletWeapon)(object)__instance))
				{
					((PlayerInventoryBase)((Weapon)__instance).m_inventory).DoReload();
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PlayerSync__RegisterFiredBullets__Patch
		{
			private static bool Prefix(PlayerSync __instance)
			{
				if (!__instance.m_agent.Owner.IsLocal || !Settings.SilentWeapon)
				{
					return true;
				}
				return false;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Weapon__ApplyRecoil__Patch
		{
			private static bool Prefix()
			{
				return !Settings.NoRecoil;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class BulletWeapon__OnWield__Patch
		{
			private static void Postfix(ref BulletWeapon __instance)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Invalid comparison between Unknown and I4
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Expected O, but got Unknown
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				if ((int)GameStateManager.Current.m_currentStateName == 10 && IsWeaponOwner(__instance))
				{
					if (!WeaponInstanceArchetypeDataLookup.TryGetValue(((GameDataBlockBase<ArchetypeDataBlock>)(object)((ItemEquippable)__instance).ArchetypeData).persistentID, out var value))
					{
						WeaponInstanceArchetypeDataLookup.Add(((GameDataBlockBase<ArchetypeDataBlock>)(object)((ItemEquippable)__instance).ArchetypeData).persistentID, AdminUtils.CopyProperties<ArchetypeDataBlock>(((ItemEquippable)__instance).ArchetypeData, new ArchetypeDataBlock()));
					}
					else
					{
						((ItemEquippable)__instance).ArchetypeData = value;
					}
					if (Settings.NoDamageFalloff)
					{
						((ItemEquippable)__instance).ArchetypeData.DamageFalloff = FalloffBlocker;
					}
					if (Settings.NoRecoil)
					{
						((ItemEquippable)__instance).ArchetypeData.RecoilDataID = 0u;
					}
					if (Settings.NoSpread)
					{
						((ItemEquippable)__instance).ArchetypeData.AimSpread = 0f;
						((ItemEquippable)__instance).ArchetypeData.HipFireSpread = 0f;
						((ItemEquippable)__instance).ArchetypeData.ShotgunBulletSpread = 0;
						((ItemEquippable)__instance).ArchetypeData.ShotgunConeSize = 1;
					}
					SetupClearSight(((Component)__instance).gameObject, Settings.ClearSight);
				}
			}
		}

		private static Dictionary<uint, ArchetypeDataBlock> WeaponInstanceArchetypeDataLookup = new Dictionary<uint, ArchetypeDataBlock>();

		private static List<string> ClearSightShaderProps = new List<string> { "falloff", "distortion", "dirt" };

		private static List<string> ClearSightCompNames = new List<string> { "thermal", "glass" };

		private static Vector2 FalloffBlocker = new Vector2(1000f, 1001f);

		private static int EnemyDamagableLayerMask;

		private static int BulletPiercingPassMask;

		private static int BulletWeaponRayMask;

		public override string Name => "武器加强";

		public override string Description => "增强武器属性";

		public override FeatureGroup Group => EntryPoint.Groups.Weapon;

		[FeatureConfig]
		public static WeaponEnhanceSettings Settings { get; set; }

		public override void Init()
		{
			DevConsole.AddCommand(Command.Create<bool?>("ClearSight", "清晰瞄具", "清晰瞄具", Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<bool?>)delegate(bool? enable)
			{
				if (!enable.HasValue)
				{
					enable = !Settings.ClearSight;
				}
				Settings.ClearSight = enable.Value;
				DevConsole.LogSuccess((object)("已" + (enable.Value ? "启用" : "禁用") + " 清晰瞄具"));
			}, (Action)delegate
			{
				DevConsole.LogVariable("清晰瞄具", (object)Settings.ClearSight, "");
			}), false);
			DevConsole.AddCommand(Command.Create<bool?>("NoDamageFalloff", "无伤害衰减", "无伤害衰减", Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<bool?>)delegate(bool? enable)
			{
				if (!enable.HasValue)
				{
					enable = !Settings.NoDamageFalloff;
				}
				Settings.NoDamageFalloff = enable.Value;
				DevConsole.LogSuccess((object)("已" + (enable.Value ? "启用" : "禁用") + " 无伤害衰减"));
			}, (Action)delegate
			{
				DevConsole.LogVariable("无伤害衰减", (object)Settings.NoDamageFalloff, "");
			}), false);
			DevConsole.AddCommand(Command.Create<bool?>("NoSpread", "无弹道扩散", "无弹道扩散", Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<bool?>)delegate(bool? enable)
			{
				if (!enable.HasValue)
				{
					enable = !Settings.NoSpread;
				}
				Settings.NoSpread = enable.Value;
				DevConsole.LogSuccess((object)("已" + (enable.Value ? "启用" : "禁用") + " 无弹道扩散"));
			}, (Action)delegate
			{
				DevConsole.LogVariable("无弹道扩散", (object)Settings.NoSpread, "");
			}), false);
			DevConsole.AddCommand(Command.Create<bool?>("NoRecoil", "无后座", "无后座", Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<bool?>)delegate(bool? enable)
			{
				if (!enable.HasValue)
				{
					enable = !Settings.NoRecoil;
				}
				Settings.NoRecoil = enable.Value;
				DevConsole.LogSuccess((object)("已" + (enable.Value ? "启用" : "禁用") + " 无后座"));
			}, (Action)delegate
			{
				DevConsole.LogVariable("无后座", (object)Settings.NoRecoil, "");
			}), false);
			DevConsole.AddCommand(Command.Create<bool?>("WallHack", "子弹穿墙", "子弹穿墙", Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<bool?>)delegate(bool? enable)
			{
				if (!enable.HasValue)
				{
					enable = !Settings.WallHack;
				}
				Settings.WallHack = enable.Value;
				DevConsole.LogSuccess((object)("已" + (enable.Value ? "启用" : "禁用") + " 子弹穿墙"));
			}, (Action)delegate
			{
				DevConsole.LogVariable("子弹穿墙", (object)Settings.WallHack, "");
			}), false);
			DevConsole.AddCommand(Command.Create<bool?>("SilentWeapon", "静音枪", "静音枪", Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<bool?>)delegate(bool? enable)
			{
				if (!enable.HasValue)
				{
					enable = !Settings.SilentWeapon;
				}
				Settings.SilentWeapon = enable.Value;
				DevConsole.LogSuccess((object)("已" + (enable.Value ? "启用" : "禁用") + " 静音枪"));
			}, (Action)delegate
			{
				DevConsole.LogVariable("静音枪", (object)Settings.SilentWeapon, "");
			}), false);
			DevConsole.AddCommand(Command.Create<bool?>("AutoReload", "自动上弹", "优先消耗后备弹药", Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<bool?>)delegate(bool? enable)
			{
				if (!enable.HasValue)
				{
					enable = !Settings.AutoReload;
				}
				Settings.AutoReload = enable.Value;
				DevConsole.LogSuccess((object)("已" + (enable.Value ? "启用" : "禁用") + " 自动上弹"));
			}, (Action)delegate
			{
				DevConsole.LogVariable("静音枪", (object)Settings.AutoReload, "");
			}), false);
		}

		public override void OnGameDataInitialized()
		{
			EnemyDamagableLayerMask = 1 << LayerManager.LAYER_ENEMY_DAMAGABLE;
			BulletPiercingPassMask = LayerManager.MASK_BULLETWEAPON_PIERCING_PASS;
			BulletWeaponRayMask = LayerManager.MASK_BULLETWEAPON_RAY;
		}

		private static bool IsWeaponOwner(BulletWeapon bulletWeapon)
		{
			if ((Object)(object)bulletWeapon == (Object)null || (Object)(object)((Item)bulletWeapon).Owner == (Object)null)
			{
				return false;
			}
			return ((Item)bulletWeapon).Owner.Owner.IsLocal;
		}

		private static void SetupClearSight(GameObject baseGO, bool enable)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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_00d3: Invalid comparison between Unknown and I4
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Invalid comparison between Unknown and I4
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Invalid comparison between Unknown and I4
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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)
			foreach (Transform componentsInChild in baseGO.GetComponentsInChildren<Transform>())
			{
				string text = ((Object)componentsInChild).name.ToLower(CultureInfo.CurrentCulture);
				foreach (string clearSightCompName in ClearSightCompNames)
				{
					if (!text.Contains(clearSightCompName))
					{
						continue;
					}
					MeshRenderer component = ((Component)componentsInChild).gameObject.GetComponent<MeshRenderer>();
					if ((Object)(object)component == (Object)null)
					{
						continue;
					}
					Material material = ((Renderer)component).material;
					Shader shader = ((Renderer)component).material.shader;
					for (int i = 0; i < shader.GetPropertyCount(); i++)
					{
						string text2 = shader.GetPropertyName(i).ToLowerInvariant();
						ShaderPropertyType propertyType = shader.GetPropertyType(i);
						int propertyNameId = shader.GetPropertyNameId(i);
						foreach (string clearSightShaderProp in ClearSightShaderProps)
						{
							if (text2.Contains(clearSightShaderProp))
							{
								if ((int)propertyType == 2 || (int)propertyType == 3)
								{
									float num = (enable ? 0f : shader.GetPropertyDefaultFloatValue(i));
									material.SetFloat(propertyNameId, num);
								}
								else if ((int)propertyType == 1)
								{
									Vector4 val = (enable ? Vector4.zero : shader.GetPropertyDefaultVectorValue(i));
									material.SetVector(propertyNameId, val);
								}
							}
						}
					}
				}
			}
		}
	}
}
namespace Hikaria.AdminSystem.Features.Security
{
	[DisallowInGameToggle]
	[EnableFeatureByDefault]
	public class AntiEnemySpawn : Feature
	{
		public class AntiSpawnSettings
		{
			[Localized]
			public enum PunishmentMode
			{
				NoneAndLog,
				Kick,
				KickAndBan
			}

			[FSDisplayName("反刷怪")]
			public bool EnableAntiSpawn { get; set; } = true;


			[FSDisplayName("惩罚好友")]
			[FSDescription("是否惩罚好友")]
			public bool PunishFriends { get; set; }

			[FSDisplayName("惩罚方式")]
			[FSDescription("当玩家尝试刷怪时如何进行惩罚")]
			public PunishmentMode Punishment { get; set; } = PunishmentMode.Kick;

		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class SNet_Replication__RegisterReplicationManager__Patch
		{
			private static void Postfix(ref SNet_ReplicationManager manager)
			{
				SNet_ReplicationManager<pEnemyGroupSpawnData, SNet_DynamicReplicator<pEnemyGroupSpawnData>> val = ((Il2CppObjectBase)manager).TryCast<SNet_ReplicationManager<pEnemyGroupSpawnData, SNet_DynamicReplicator<pEnemyGroupSpawnData>>>();
				if (val != null)
				{
					FeatureLogger.Info("Find SNet_ReplicationManager of pEnemyGroupSpawnData");
					Action<pEnemyGroupSpawnData> _original1 = val.m_spawnRequestPacket.ReceiveAction;
					Action<pEnemyGroupSpawnData> action = delegate(pEnemyGroupSpawnData data)
					{
						//IL_0055: Unknown result type (might be due to invalid IL or missing references)
						if (Settings.EnableAntiSpawn && SNet.IsMaster && !SNet.Capture.IsCheckpointRecall)
						{
							bool flag2 = true;
							SNet_Player player2 = default(SNet_Player);
							if (SNet.Replication.TryGetLastSender(ref player2, false))
							{
								flag2 = PunishPlayer(player2);
							}
							if (flag2)
							{
								FeatureLogger.Notice("刷怪行为被拦截!");
								return;
							}
						}
						_original1?.Invoke(data);
					};
					val.m_spawnRequestPacket.ReceiveAction = Action<pEnemyGroupSpawnData>.op_Implicit(action);
					return;
				}
				EnemyReplicationManager val2 = ((Il2CppObjectBase)manager).TryCast<EnemyReplicationManager>();
				if (val2 == null)
				{
					return;
				}
				FeatureLogger.Info("Find SNet_ReplicationManager of pEnemySpawnData");
				Action<pEnemySpawnData> _original2 = ((SNet_ReplicationManager<pEnemySpawnData, EnemyReplicator>)(object)val2).m_spawnRequestPacket.ReceiveAction;
				Action<pEnemySpawnData> action2 = delegate(pEnemySpawnData data)
				{
					//IL_0055: Unknown result type (might be due to invalid IL or missing references)
					if (Settings.EnableAntiSpawn && SNet.IsMaster && !SNet.Capture.IsCheckpointRecall)
					{
						bool flag = true;
						SNet_Player player = default(SNet_Player);
						if (SNet.Replication.TryGetLastSender(ref player, false))
						{
							flag = PunishPlayer(player);
						}
						if (flag)
						{
							FeatureLogger.Notice("刷怪行为被拦截!");
							return;
						}
					}
					_original2?.Invoke(data);
				};
				((SNet_ReplicationManager<pEnemySpawnData, EnemyReplicator>)(object)val2).m_spawnRequestPacket.ReceiveAction = Action<pEnemySpawnData>.op_Implicit(action2);
			}
		}

		public override string Name => "反刷怪";

		public override string Description => "阻止玩家刷怪并给予惩罚";

		public override FeatureGroup Group => EntryPoint.Groups.Security;

		public static IArchiveLogger FeatureLogger { get; set; }

		public static AntiEnemySpawn Instance { get; private set; }

		[FeatureConfig]
		public static AntiSpawnSettings Settings { get; set; }

		public static bool PunishPlayer(SNet_Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return true;
			}
			if (SharedUtils.IsFriend(player) && !Settings.PunishFriends)
			{
				FeatureLogger.Notice("好友玩家 " + player.NickName + " 正在尝试刷怪!");
				return false;
			}
			switch (Settings.Punishment)
			{
			case AntiSpawnSettings.PunishmentMode.KickAndBan:
				PlayerLobbyManagement.BanPlayer(player, true);
				break;
			case AntiSpawnSettings.PunishmentMode.Kick:
				PlayerLobbyManagement.KickPlayer(player);
				break;
			}
			FeatureLogger.Notice($"玩家 {player.NickName} 正在尝试刷怪!({Settings.Punishment})");
			return true;
		}
	}
}
namespace Hikaria.AdminSystem.Features.Player
{
	[DoNotSaveToConfig]
	[EnableFeatureByDefault]
	[DisallowInGameToggle]
	internal class DisableStamina : Feature
	{
		public class DisableStaminaSettings
		{
			[FSDisplayName("禁用心率")]
			public bool DisableStamina { get; set; }

			[FSDisplayName("禁用附近敌人对自身移动速度的影响")]
			public bool DisableNearByEnemyMoveSpeedMultiplier { get; set; }
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PlayerStamina_LateUpdate_Patch
		{
			private static void Postfix(PlayerStamina __instance)
			{
				if (__instance.m_owner.Owner.IsLocal && Settings.DisableStamina)
				{
					__instance.ResetStamina();
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PlayerEnemyCollision_FindNearbyEnemiesMovementReduction_Patch
		{
			private static void Postfix(PlayerEnemyCollision __instance, ref float __result)
			{
				if (__instance.m_owner.Owner.IsLocal && Settings.DisableNearByEnemyMoveSpeedMultiplier)
				{
					__result = 1f;
				}
			}
		}

		public override string Name => "禁用心率系统";

		public override string Description => "启用以禁用心率系统";

		public override FeatureGroup Group => EntryPoint.Groups.Player;

		[FeatureConfig]
		public static DisableStaminaSettings Settings { get; private set; }

		public override void Init()
		{
			DevConsole.AddCommand(Command.Create<bool?>("DisableStamina", "禁用心率", "禁用心率", Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<bool?>)delegate(bool? enable)
			{
				if (!enable.HasValue)
				{
					enable = !Settings.DisableStamina;
				}
				Settings.DisableStamina = enable.Value;
				DevConsole.LogSuccess((object)("已" + (enable.Value ? "启用" : "禁用") + " 禁用心率"));
			}, (Action)delegate
			{
				DevConsole.LogVariable("禁用心率", (object)Settings.DisableStamina, "");
			}), false);
			DevConsole.AddCommand(Command.Create<bool?>("DisableNearByEnemyMoveSpeedMultiplier", "禁用附近敌人对自身移动速度的影响", "禁用附近敌人对自身移动速度的影响", Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<bool?>)delegate(bool? enable)
			{
				if (!enable.HasValue)
				{
					enable = !Settings.DisableNearByEnemyMoveSpeedMultiplier;
				}
				Settings.DisableNearByEnemyMoveSpeedMultiplier = enable.Value;
				DevConsole.LogSuccess((object)("已" + (enable.Value ? "启用" : "禁用") + " 禁用附近敌人对自身移动速度的影响"));
			}, (Action)delegate
			{
				DevConsole.LogVariable("禁用附近敌人对自身移动速度的影响", (object)Settings.DisableNearByEnemyMoveSpeedMultiplier, "");
			}), false);
		}
	}
	[EnableFeatureByDefault]
	[DisallowInGameToggle]
	[DoNotSaveToConfig]
	public class GodMode : Feature, IOnSessionMemberChanged
	{
		public class GodModeSettings
		{
			[FSDisplayName("玩家设置")]
			[FSReadOnly(true)]
			[FSInline]
			public List<GodModeEntry> PlayerSettings
			{
				get
				{
					return GodModeLookup.Values.ToList();
				}
				set
				{
				}
			}
		}

		public class GodModeEntry
		{
			[FSDisplayName("昵称")]
			[FSSeparator]
			[FSReadOnly(true)]
			public string NickName
			{
				get
				{
					SNet_Player val = default(SNet_Player);
					if (SNet.TryGetPlayer(Lookup, ref val))
					{
						return val.NickName;
					}
					return Lookup.ToString();
				}
				set
				{
				}
			}

			[FSIgnore]
			public ulong Lookup { get; set; }

			[FSDisplayName("忽略所有伤害")]
			public bool IgnoreAllDamage { get; set; }

			[FSDisplayName("忽略感染")]
			public bool IgnoreInfection { get; set; }

			[FSDisplayName("无法倒地")]
			public bool CannotDie { get; set; }
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PlayerLocomotion__ChangeState__Patch
		{
			private static void Postfix(PlayerLocomotion __instance, PLOC_State state)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Invalid comparison between Unknown and I4
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				if ((int)GameStateManager.CurrentStateName == 10)
				{
					PlayerAgent owner = __instance.m_owner;
					ulong lookup = owner.Owner.Lookup;
					if (GodModeLookup.TryGetValue(lookup, out var value) && value.CannotDie && (int)state == 7)
					{
						AgentReplicatedActions.PlayerReviveAction(owner, (PlayerAgent)(object)AdminUtils.LocalPlayerAgent, ((Agent)owner).Position);
						DevConsole.Log((object)("<color=green>已复活玩家 " + owner.PlayerName + "</color>"));
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_PlayerDamageBase__ReceiveSetHealth__Patch
		{
			private static void Prefix(Dam_PlayerDamageBase __instance, ref pSetHealthData data)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				if ((int)GameStateManager.CurrentStateName == 10)
				{
					ulong lookup = __instance.Owner.Owner.Lookup;
					if (GodModeLookup.TryGetValue(lookup, out var value) && value.IgnoreAllDamage)
					{
						((SFloat16)(ref data.health)).Set(25f, 25f);
						((Dam_SyncedDamageBase)__instance).m_setHealthPacket.Send(data, (SNet_ChannelType)4);
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_PlayerDamageBase__ReceiveSetDead__Patch
		{
			private static bool Prefix(Dam_PlayerDamageBase __instance, ref pSetDeadData data)
			{
				PlayerAgent owner = __instance.Owner;
				ulong lookup = owner.Owner.Lookup;
				if (!GodModeLookup.TryGetValue(lookup, out var value) || !value.CannotDie)
				{
					return true;
				}
				if (owner.Owner.IsLocal || SNet.IsMaster)
				{
					return false;
				}
				return true;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_PlayerDamageLocal__ReceiveSetHealth__Patch
		{
			private static void Prefix(Dam_PlayerDamageLocal __instance, ref pSetHealthData data)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				if ((int)GameStateManager.CurrentStateName == 10)
				{
					ulong lookup = ((Dam_PlayerDamageBase)__instance).Owner.Owner.Lookup;
					if (GodModeLookup.TryGetValue(lookup, out var value) && value.IgnoreAllDamage)
					{
						((SFloat16)(ref data.health)).Set(25f, 25f);
						((Dam_SyncedDamageBase)__instance).m_setHealthPacket.Send(data, (SNet_ChannelType)4);
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_PlayerDamageLocal__ReceiveSetDead__Patch
		{
			private static bool Prefix(Dam_PlayerDamageLocal __instance)
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				ulong lookup = ((Dam_PlayerDamageBase)__instance).Owner.Owner.Lookup;
				if (!GodModeLookup.TryGetValue(lookup, out var value) || !value.CannotDie)
				{
					return true;
				}
				AgentReplicatedActions.PlayerReviveAction((PlayerAgent)(object)AdminUtils.LocalPlayerAgent, (PlayerAgent)(object)AdminUtils.LocalPlayerAgent, ((Agent)AdminUtils.LocalPlayerAgent).Position);
				return false;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_PlayerDamageLocal__ModifyInfection__Patch
		{
			private static void Prefix(Dam_PlayerDamageLocal __instance, ref pInfection data)
			{
				//IL_0036: 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)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				ulong lookup = ((Dam_PlayerDamageBase)__instance).Owner.Owner.Lookup;
				if (GodModeLookup.TryGetValue(lookup, out var value) && value.IgnoreInfection)
				{
					data.amount = 0f;
					data.mode = (pInfectionMode)0;
					data.effect = (pInfectionEffect)0;
					((Dam_PlayerDamageBase)__instance).m_receiveModifyInfectionPacket.Send(data, (SNet_ChannelType)4);
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_PlayerDamageBase__ReceiveModifyInfection__Patch
		{
			private static void Prefix(Dam_PlayerDamageBase __instance, ref pInfection data)
			{
				//IL_0036: 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)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				ulong lookup = __instance.Owner.Owner.Lookup;
				if (GodModeLookup.TryGetValue(lookup, out var value) && value.IgnoreInfection)
				{
					data.amount = 0f;
					data.mode = (pInfectionMode)0;
					data.effect = (pInfectionEffect)0;
					__instance.m_receiveModifyInfectionPacket.Send(data, (SNet_ChannelType)4);
				}
			}
		}

		public override string Name => "无敌模式";

		public override FeatureGroup Group => EntryPoint.Groups.Player;

		public static Dictionary<ulong, GodModeEntry> GodModeLookup { get; set; } = new Dictionary<ulong, GodModeEntry>();


		[FeatureConfig]
		public static GodModeSettings Settings { get; set; }

		public override void Init()
		{
			GameEventManager.RegisterSelfInGameEventManager(this);
			DevConsole.AddCommand(Command.Create<int, bool?>("IgnoreAllDamage", "无敌", "无敌", Parameter.Create("Slot", "玩家所在槽位"), Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<int, bool?>)delegate(int slot, bool? enable)
			{
				if (!AdminUtils.TryGetPlayerAgentFromSlotIndex(slot, out var player3) || !GodModeLookup.TryGetValue(player3.Owner.Lookup, out var value3))
				{
					DevConsole.LogError((object)"输入有误");
				}
				else
				{
					if (!enable.HasValue)
					{
						enable = value3.IgnoreAllDamage;
					}
					value3.IgnoreAllDamage = enable.Value;
					DevConsole.LogSuccess((object)$"已{(enable.Value ? "启用" : "禁用")} {player3.Owner.NickName} 无敌模式");
				}
			}, (Action)null), false);
			DevConsole.AddCommand(Command.Create<int, bool?>("IgnoreInfection", "免毒", "免毒", Parameter.Create("Slot", "玩家所在槽位"), Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<int, bool?>)delegate(int slot, bool? enable)
			{
				if (!AdminUtils.TryGetPlayerAgentFromSlotIndex(slot, out var player2) || !GodModeLookup.TryGetValue(player2.Owner.Lookup, out var value2))
				{
					DevConsole.LogError((object)"输入有误");
				}
				else
				{
					if (!enable.HasValue)
					{
						enable = value2.IgnoreInfection;
					}
					value2.IgnoreInfection = enable.Value;
					DevConsole.LogSuccess((object)$"已{(enable.Value ? "启用" : "禁用")} {player2.Owner.NickName} 免毒");
				}
			}, (Action)null), false);
			DevConsole.AddCommand(Command.Create<int, bool?>("CannotDie", "无法倒地", "无法倒地", Parameter.Create("Slot", "玩家所在槽位"), Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<int, bool?>)delegate(int slot, bool? enable)
			{
				if (!AdminUtils.TryGetPlayerAgentFromSlotIndex(slot, out var player) || !GodModeLookup.TryGetValue(player.Owner.Lookup, out var value))
				{
					DevConsole.LogError((object)"输入有误");
				}
				else
				{
					if (!enable.HasValue)
					{
						enable = value.CannotDie;
					}
					value.CannotDie = enable.Value;
					DevConsole.LogSuccess((object)$"已{(enable.Value ? "启用" : "禁用")} {player.Owner.NickName} 无法倒地");
				}
			}, (Action)null), false);
		}

		public override void OnGameStateChanged(int state)
		{
			if ((byte)state != 11)
			{
				return;
			}
			foreach (GodModeEntry value in GodModeLookup.Values)
			{
				value.IgnoreAllDamage = false;
				value.IgnoreInfection = false;
				value.CannotDie = false;
			}
		}

		public void OnSessionMemberChanged(SNet_Player player, SessionMemberEvent playerEvent)
		{
			if (!player.IsValid())
			{
				return;
			}
			switch (playerEvent)
			{
			case SessionMemberEvent.JoinSessionHub:
			{
				GodModeEntry value = new GodModeEntry
				{
					Lookup = player.Lookup,
					IgnoreAllDamage = false,
					IgnoreInfection = false,
					CannotDie = false
				};
				GodModeLookup.TryAdd(player.Lookup, value);
				break;
			}
			case SessionMemberEvent.LeftSessionHub:
				if (player.IsLocal)
				{
					GodModeLookup.Clear();
				}
				else
				{
					GodModeLookup.Remove(player.Lookup);
				}
				break;
			}
		}
	}
	[EnableFeatureByDefault]
	[DisallowInGameToggle]
	[DoNotSaveToConfig]
	public class InfiniteResource : Feature, IOnSessionMemberChanged
	{
		public class InfiniteResourceSettings
		{
			[FSDisplayName("玩家设置")]
			[FSReadOnly(true)]
			public List<InfiniteResourceEntry> PlayerSettings
			{
				get
				{
					return InfResourceLookup.Values.ToList();
				}
				set
				{
				}
			}
		}

		public class InfiniteResourceEntry
		{
			[FSSeparator]
			[FSDisplayName("昵称")]
			[FSReadOnly(true)]
			public string NickName
			{
				get
				{
					SNet_Player val = default(SNet_Player);
					if (SNet.TryGetPlayer(Lookup, ref val))
					{
						return val.NickName;
					}
					return Lookup.ToString();
				}
				set
				{
				}
			}

			[FSIgnore]
			public ulong Lookup { get; set; }

			[FSDisplayName("无限资源")]
			public bool InfResource { get; set; }

			[FSDisplayName("禁用资源")]
			[FSDescription("对自身没用")]
			public bool NoResource { get; set; }

			[FSDisplayName("无限哨戒炮")]
			public bool InfSentry { get; set; }

			[FSDisplayName("强制部署")]
			[FSDescription("对自身没用")]
			public bool ForceDeploy { get; set; }
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PlayerBackpack__SetDeployed__Patch
		{
			private static void Prefix(PlayerBackpack __instance, InventorySlot slot, ref bool mode)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Invalid comparison between Unknown and I4
				//IL_0036: 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_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				if (Feature.CurrentGameState == 10 && (int)slot == 3 && mode)
				{
					SNet_Player owner = __instance.Owner;
					if (InfResourceLookup[owner.Lookup].InfSentry)
					{
						mode = false;
						pInventoryItemStatus val = default(pInventoryItemStatus);
						((pPlayer)(ref val.sourcePlayer)).SetPlayer(owner);
						val.slot = slot;
						val.status = (eInventoryItemStatus)0;
						PlayerBackpackManager.Current.m_itemStatusSync.Send(val, (SNet_ChannelType)4);
						((Il2CppObjectBase)owner.PlayerAgent).Cast<PlayerAgent>().GiveAmmoRel((PlayerAgent)(object)AdminUtils.LocalPlayerAgent, 0f, 0f, 1f);
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class SentryGunInstance_Firing_Bullets__UpdateAmmo__Patch
		{
			private static void Prefix(SentryGunInstance_Firing_Bullets __instance, ref int bullets)
			{
				if (Feature.CurrentGameState != 10)
				{
					return;
				}
				SentryGunInstance val = ((Il2CppObjectBase)__instance.m_core).Cast<SentryGunInstance>();
				if (!((Object)(object)((Item)val).Owner == (Object)null))
				{
					SNet_Player owner = __instance.m_core.Owner.Owner;
					_ = owner.Lookup;
					if (InfResourceLookup[owner.Lookup].InfResource)
					{
						int num = (int)(val.AmmoMaxCap / val.CostOfBullet);
						int num2 = (int)(val.Ammo / val.CostOfBullet);
						bullets = num - num2;
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PlayerAmmoStorage__UpdateBulletsInPack__Patch
		{
			private static void Prefix(PlayerAmmoStorage __instance, AmmoType ammoType, ref int bulletCount)
			{
				//IL_002f: 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_003b: Invalid comparison between Unknown and I4
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Invalid comparison between Unknown and I4
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Invalid comparison between Unknown and I4
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				if (Feature.CurrentGameState != 10)
				{
					return;
				}
				SNet_Player owner = __instance.m_playerBackpack.Owner;
				if (InfResourceLookup[owner.Lookup].InfResource)
				{
					int num = (bulletCount = __instance.GetBulletMaxCap(ammoType));
					if ((int)ammoType == 3)
					{
						__instance.SetAmmo(ammoType, (float)num * __instance.ResourcePackAmmo.CostOfBullet);
					}
					else if ((int)ammoType == 2)
					{
						__instance.SetAmmo(ammoType, (float)num * __instance.ClassAmmo.CostOfBullet);
					}
					else if ((int)ammoType == 5)
					{
						__instance.SetAmmo(ammoType, (float)num * __instance.ConsumableAmmo.CostOfBullet);
					}
				}
			}

			private static void Postfix(PlayerAmmoStorage __instance)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: 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)
				SNet_Player owner = __instance.m_playerBackpack.Owner;
				if (InfResourceLookup[owner.Lookup].InfResource)
				{
					pAmmoStorageData storageData = __instance.GetStorageData();
					__instance.m_playerBackpack.OnStorageUpdatedCallback?.Invoke(__instance.m_playerBackpack);
					PlayerBackpackManager.Current.m_ammoStoragePacket.Send(storageData, (SNet_ChannelType)2);
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class SentryGunInstance_Sync__OnTargetingData__Patch
		{
			private static void Postfix(SentryGunInstance_Sync __instance)
			{
				if (Feature.CurrentGameState == 10 && !SNet.IsMaster)
				{
					SentryGunInstance val = ((Il2CppObjectBase)__instance.m_core).Cast<SentryGunInstance>();
					SNet_Player owner = ((Item)val).Owner.Owner;
					if (InfResourceLookup.TryGetValue(owner.Lookup, out var value) && value.InfResource)
					{
						int num = (int)(val.AmmoMaxCap / val.CostOfBullet);
						__instance.ForceReliableAmmoUpdate((float)num);
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PlayerBackpackManager__ReceiveAmmoSync__Patch
		{
			private static void Prefix(ref pAmmoStorageData data)
			{
				SNet_Player val = default(SNet_Player);
				PlayerBackpack val2 = default(PlayerBackpack);
				if (Feature.CurrentGameState == 10 && SNet.Core.TryGetPlayer(data.PlayerLookup, ref val, false) && PlayerBackpackManager.TryGetBackpack(val, ref val2) && InfResourceLookup.TryGetValue(val.Lookup, out var value))
				{
					if (value.InfResource)
					{
						((DevFloat32)(ref data.standardAmmo)).Set(val2.AmmoStorage.StandardAmmo.AmmoMaxCap + (float)val2.AmmoStorage.StandardAmmo.BulletClipSize * val2.AmmoStorage.StandardAmmo.CostOfBullet, 500f);
						((DevFloat32)(ref data.specialAmmo)).Set(val2.AmmoStorage.SpecialAmmo.AmmoMaxCap + (float)val2.AmmoStorage.SpecialAmmo.BulletClipSize * val2.AmmoStorage.SpecialAmmo.CostOfBullet, 500f);
						((DevFloat32)(ref data.classAmmo)).Set(val2.AmmoStorage.ClassAmmo.AmmoMaxCap, 500f);
						((DevFloat32)(ref data.resourcePackAmmo)).Set(val2.AmmoStorage.ResourcePackAmmo.AmmoMaxCap, 500f);
						((DevFloat32)(ref data.consumableAmmo)).Set(val2.AmmoStorage.ConsumableAmmo.AmmoMaxCap, 500f);
					}
					else if (value.NoResource)
					{
						((DevFloat32)(ref data.standardAmmo)).Set(-500f, 500f);
						((DevFloat32)(ref data.specialAmmo)).Set(-500f, 500f);
						((DevFloat32)(ref data.classAmmo)).Set(-500f, 500f);
						((DevFloat32)(ref data.resourcePackAmmo)).Set(-500f, 500f);
						((DevFloat32)(ref data.consumableAmmo)).Set(-500f, 500f);
					}
				}
			}

			private static void Postfix(ref pAmmoStorageData data)
			{
				//IL_0059: 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_0087: 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_009f: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
				SNet_Player val = default(SNet_Player);
				PlayerBackpack val2 = default(PlayerBackpack);
				if (Feature.CurrentGameState != 10 || !SNet.Core.TryGetPlayer(data.PlayerLookup, ref val, false) || !PlayerBackpackManager.TryGetBackpack(val, ref val2) || !InfResourceLookup.TryGetValue(val.Lookup, out var value))
				{
					return;
				}
				if (value.InfResource || value.NoResource)
				{
					PlayerBackpackManager.Current.m_ammoStoragePacket.Send(data, (SNet_ChannelType)2);
				}
				if (value.ForceDeploy)
				{
					pInventoryItemStatus val3 = default(pInventoryItemStatus);
					((pPlayer)(ref val3.sourcePlayer)).SetPlayer(val);
					val3.status = (eInventoryItemStatus)1;
					val3.slot = (InventorySlot)10;
					PlayerBackpackManager.Current.m_itemStatusSync.Send(val3, (SNet_ChannelType)4, val);
					val3.slot = (InventorySlot)1;
					PlayerBackpackManager.Current.m_itemStatusSync.Send(val3, (SNet_ChannelType)4, val);
					val3.slot = (InventorySlot)2;
					PlayerBackpackManager.Current.m_itemStatusSync.Send(val3, (SNet_ChannelType)4, val);
					val3.slot = (InventorySlot)3;
					PlayerBackpackManager.Current.m_itemStatusSync.Send(val3, (SNet_ChannelType)4, val);
					if (AdminUtils.TryGetPlayerAgentFromSlotIndex(val.PlayerSlotIndex(), out var player))
					{
						player.Sync.WantsToWieldSlot((InventorySlot)0, false);
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PlayerSync__SyncInventoryStatus__Patch
		{
			private static void Postfix(PlayerSync __instance, pInventoryStatus data)
			{
				//IL_0052: 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)
				if (Feature.CurrentGameState == 10 && !((Object)(object)__instance.m_agent == (Object)null) && !((Object)(object)__instance.m_agent.Owner == (Object)null) && InfResourceLookup.TryGetValue(__instance.m_agent.Owner.Lookup, out var value) && value.ForceDeploy && (int)data.wieldedSlot != 0)
				{
					__instance.WantsToWieldSlot((InventorySlot)0, false);
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PlayerBackpackManager__SendLocalAmmoData__Patch
		{
			private static void Prefix()
			{
				//IL_002f: 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)
				if (Feature.CurrentGameState == 10 && InfResourceLookup[SNet.LocalPlayer.Lookup].InfResource)
				{
					pAmmoStorageData storageData = PlayerBackpackManager.LocalBackpack.AmmoStorage.GetStorageData();
					if (PlayerBackpackManager.LocalBackpack.AmmoStorage.GetBulletsInPack((AmmoType)0) < PlayerBackpackManager.LocalBackpack.AmmoStorage.GetBulletMaxCap((AmmoType)0))
					{
						((DevFloat32)(ref storageData.standardAmmo)).Set(PlayerBackpackManager.LocalBackpack.AmmoStorage.StandardAmmo.AmmoMaxCap, 500f);
					}
					if (PlayerBackpackManager.LocalBackpack.AmmoStorage.GetBulletsInPack((AmmoType)1) < PlayerBackpackManager.LocalBackpack.AmmoStorage.GetBulletMaxCap((AmmoType)1))
					{
						((DevFloat32)(ref storageData.specialAmmo)).Set(PlayerBackpackManager.LocalBackpack.AmmoStorage.SpecialAmmo.AmmoMaxCap, 500f);
					}
					PlayerBackpackManager.LocalBackpack.AmmoStorage.SetStorageData(ref storageData);
				}
			}
		}

		public override string Name => "无限资源";

		public override FeatureGroup Group => EntryPoint.Groups.Player;

		[FeatureConfig]
		public static InfiniteResourceSettings Settings { get; set; }

		public static Dictionary<ulong, InfiniteResourceEntry> InfResourceLookup { get; set; } = new Dictionary<ulong, InfiniteResourceEntry>();


		public override void Init()
		{
			GameEventManager.RegisterSelfInGameEventManager(this);
			DevConsole.AddCommand(Command.Create<int, bool?>("InfResource", "无限资源", "无限资源", Parameter.Create("Slot", "玩家所在槽位"), Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<int, bool?>)delegate(int slot, bool? enable)
			{
				if (!AdminUtils.TryGetPlayerAgentFromSlotIndex(slot, out var player4) || !InfResourceLookup.TryGetValue(player4.Owner.Lookup, out var value4))
				{
					DevConsole.LogError((object)"输入有误");
				}
				else
				{
					if (!enable.HasValue)
					{
						enable = value4.InfResource;
					}
					value4.InfResource = enable.Value;
					DevConsole.LogSuccess((object)$"已{(enable.Value ? "启用" : "禁用")} {player4.Owner.NickName} 无限资源");
				}
			}, (Action)null), false);
			DevConsole.AddCommand(Command.Create<int, bool?>("NoResource", "禁用资源", "禁用资源", Parameter.Create("Slot", "玩家所在槽位"), Parameter.Create("Enable", "True: 启用, False: 禁用"), (Action<int, bool?>)delegate(int slot, bool? enable)
			{
				if (!AdminUtils.TryGetPlayerAgentFromSlotIndex(slot, out var player3) || !InfResourceLookup.TryGetValue(player3.Owner.Lookup, out var value3))
				{
					DevConsole.LogError((object)"输入有误");
				}
				else
				{
					if (!enable.HasValue)
					{
						enable = value3.NoResource;
					}
					value3.NoResource = enable.Value;
					DevConsole.LogSuccess((object)$"已{(enable.Value ? "启用" : "禁用")} {player3.Owner.NickName} 禁用资源");
				}
			}, (Action)null), false