Decompiled source of GunRangeNoLimit v4.0.2

GunRangeNoLimit.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("zabuMod")]
[assembly: AssemblyTitle("zabuMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace REPOJP.GunRangeNoLimit
{
	[BepInPlugin("REPOJP.GunRangeNoLimit", "GunRangeNoLimit", "4.0.2")]
	public sealed class GunRangeNoLimitPlugin : BaseUnityPlugin
	{
		private static class ItemGunPatches
		{
			[HarmonyPatch(typeof(ItemGun), "Start")]
			[HarmonyPostfix]
			private static void StartPostfix(ItemGun __instance)
			{
				ApplyItemGunRange(__instance);
			}

			[HarmonyPatch(typeof(ItemGun), "Shoot")]
			[HarmonyPrefix]
			private static void ShootPrefix(ItemGun __instance)
			{
				ApplyItemGunRange(__instance);
			}

			[HarmonyPatch(typeof(ItemGun), "ShootRPC")]
			[HarmonyPrefix]
			private static void ShootRPCPrefix(ItemGun __instance)
			{
				ApplyItemGunRange(__instance);
			}
		}

		private static class ItemGunLaserPatches
		{
			[HarmonyPatch(typeof(ItemGunLaser), "LaserShooting")]
			[HarmonyPrefix]
			private static void LaserShootingPrefix(ItemGunLaser __instance)
			{
				if (!((Object)(object)__instance == (Object)null))
				{
					ItemGun component = ((Component)__instance).GetComponent<ItemGun>();
					ApplyItemGunRange(component);
				}
			}
		}

		private static class ArenaCartCannonPatches
		{
			[HarmonyPatch(typeof(ItemCartCannon), "ShootLogic")]
			[HarmonyTranspiler]
			private static IEnumerable<CodeInstruction> ShootLogicTranspiler(IEnumerable<CodeInstruction> instructions)
			{
				MethodInfo replacementMethod = AccessTools.Method(typeof(GunRangeNoLimitPlugin), "GetArenaCartCannonRange", (Type[])null, (Type[])null);
				return ReplaceFloatConstant(instructions, 25f, replacementMethod);
			}
		}

		private static class ArenaCartLaserPatches
		{
			[HarmonyPatch(typeof(ItemCartLaser), "StateShooting")]
			[HarmonyTranspiler]
			private static IEnumerable<CodeInstruction> StateShootingTranspiler(IEnumerable<CodeInstruction> instructions)
			{
				MethodInfo replacementMethod = AccessTools.Method(typeof(GunRangeNoLimitPlugin), "GetArenaCartLaserRange", (Type[])null, (Type[])null);
				return ReplaceFloatConstant(instructions, 15f, replacementMethod);
			}
		}

		[HarmonyPatch]
		private static class SlowProjectileSetSpawnerRpcPatch
		{
			private static bool Prepare()
			{
				Type type = AccessTools.TypeByName("SlowProjectile");
				return type != null && AccessTools.Method(type, "SetSpawnerRPC", (Type[])null, (Type[])null) != null;
			}

			private static MethodBase TargetMethod()
			{
				Type type = AccessTools.TypeByName("SlowProjectile");
				return AccessTools.Method(type, "SetSpawnerRPC", (Type[])null, (Type[])null);
			}

			[HarmonyPostfix]
			private static void Postfix(object __instance)
			{
				SlowProjectile_SetSpawnerRPC_Postfix(__instance);
			}
		}

		[HarmonyPatch]
		private static class SlowProjectileLaunchRpcPatch
		{
			private static bool Prepare()
			{
				Type type = AccessTools.TypeByName("SlowProjectile");
				return type != null && AccessTools.Method(type, "LaunchRPC", (Type[])null, (Type[])null) != null;
			}

			private static MethodBase TargetMethod()
			{
				Type type = AccessTools.TypeByName("SlowProjectile");
				return AccessTools.Method(type, "LaunchRPC", (Type[])null, (Type[])null);
			}

			[HarmonyPostfix]
			private static void Postfix(object __instance)
			{
				SlowProjectile_LaunchRPC_Postfix(__instance);
			}
		}

		[HarmonyPatch]
		private static class SlowProjectileAutoDestroyPatch
		{
			private static bool Prepare()
			{
				Type type = AccessTools.TypeByName("SlowProjectile");
				return type != null && AccessTools.Method(type, "AutoDestroy", (Type[])null, (Type[])null) != null;
			}

			private static MethodBase TargetMethod()
			{
				Type type = AccessTools.TypeByName("SlowProjectile");
				return AccessTools.Method(type, "AutoDestroy", (Type[])null, (Type[])null);
			}

			[HarmonyPrefix]
			private static bool Prefix(object __instance)
			{
				return SlowProjectile_AutoDestroy_Prefix(__instance);
			}
		}

		[HarmonyPatch]
		private static class SemiAreaOfEffectDoAreaOfEffectPatch
		{
			private static bool Prepare()
			{
				Type type = AccessTools.TypeByName("SemiAreaOfEffect");
				return type != null && AccessTools.Method(type, "DoAreaOfEffect", (Type[])null, (Type[])null) != null;
			}

			private static MethodBase TargetMethod()
			{
				Type type = AccessTools.TypeByName("SemiAreaOfEffect");
				return AccessTools.Method(type, "DoAreaOfEffect", (Type[])null, (Type[])null);
			}

			[HarmonyPrefix]
			private static void Prefix(object __instance)
			{
				SemiAreaOfEffect_DoAreaOfEffect_Prefix(__instance);
			}
		}

		[CompilerGenerated]
		private sealed class <ReplaceFloatConstant>d__79 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private float targetValue;

			public float <>3__targetValue;

			private MethodInfo replacementMethod;

			public MethodInfo <>3__replacementMethod;

			private IEnumerator<CodeInstruction> <>s__1;

			private CodeInstruction <code>5__2;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ReplaceFloatConstant>d__79(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>s__1 = null;
				<code>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>s__1 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<code>5__2 = null;
						break;
					}
					if (<>s__1.MoveNext())
					{
						<code>5__2 = <>s__1.Current;
						if (IsFloatConstant(<code>5__2, targetValue))
						{
							<code>5__2.opcode = OpCodes.Call;
							<code>5__2.operand = replacementMethod;
						}
						<>2__current = <code>5__2;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>s__1 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__1 != null)
				{
					<>s__1.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<ReplaceFloatConstant>d__79 <ReplaceFloatConstant>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<ReplaceFloatConstant>d__ = this;
				}
				else
				{
					<ReplaceFloatConstant>d__ = new <ReplaceFloatConstant>d__79(0);
				}
				<ReplaceFloatConstant>d__.instructions = <>3__instructions;
				<ReplaceFloatConstant>d__.targetValue = <>3__targetValue;
				<ReplaceFloatConstant>d__.replacementMethod = <>3__replacementMethod;
				return <ReplaceFloatConstant>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		public const string PluginGuid = "REPOJP.GunRangeNoLimit";

		public const string PluginName = "GunRangeNoLimit";

		public const string PluginVersion = "4.0.2";

		private Harmony harmony = null;

		internal static ManualLogSource Log = null;

		private static ConfigEntry<bool> cfgEnableMod = null;

		private static ConfigEntry<float> cfgRangeMultiplier = null;

		private static ConfigEntry<bool> cfgUseAbsoluteRange = null;

		private static ConfigEntry<float> cfgAbsoluteRange = null;

		private static ConfigEntry<bool> cfgApplyVisualForClients = null;

		private static ConfigEntry<bool> cfgApplyArenaWeapons = null;

		private static ConfigEntry<bool> cfgApplyStaffItems = null;

		private static ConfigEntry<float> cfgStaffRangeMultiplier = null;

		private static ConfigEntry<bool> cfgStaffUseAbsoluteRange = null;

		private static ConfigEntry<float> cfgStaffAbsoluteRange = null;

		private static ConfigEntry<float> cfgStaffProjectileSpeedMultiplier = null;

		private static ConfigEntry<float> cfgStaffAreaEffectMultiplier = null;

		private static readonly Dictionary<int, float> originalItemGunRanges = new Dictionary<int, float>();

		private static readonly HashSet<int> staffProjectileIds = new HashSet<int>();

		private static readonly Dictionary<int, float> originalStaffProjectileSpeeds = new Dictionary<int, float>();

		private static readonly Dictionary<int, Vector3> originalAreaEffectHurtColliderScales = new Dictionary<int, Vector3>();

		private static Type slowProjectileType = null;

		private static Type semiAreaOfEffectType = null;

		private static Type itemStaffTorqueType = null;

		private static Type itemStaffVoidType = null;

		private static Type itemStaffZeroGravityType = null;

		private static Type valuableStarWandType = null;

		private static Type photonViewType = null;

		private static Type rpcTargetType = null;

		private static FieldInfo slowProjectileSpeedField = null;

		private static FieldInfo slowProjectileSpawnPositionField = null;

		private static FieldInfo slowProjectileMoveDirectionField = null;

		private static FieldInfo slowProjectileDestroyedField = null;

		private static FieldInfo slowProjectileAreaOfEffectField = null;

		private static FieldInfo slowProjectileSpawnerField = null;

		private static FieldInfo slowProjectileUseExplosionField = null;

		private static FieldInfo slowProjectileUseAreaOfEffectField = null;

		private static MethodInfo slowProjectileExplosionMethod = null;

		private static MethodInfo slowProjectileDestroyRpcMethod = null;

		private static FieldInfo semiAreaOfEffectHurtColliderField = null;

		private static MethodInfo semiAreaOfEffectDoAreaOfEffectMethod = null;

		private static MethodInfo photonViewRpcMethod = null;

		private void Awake()
		{
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Expected O, but got Unknown
			try
			{
				Log = ((BaseUnityPlugin)this).Logger;
				((Component)this).transform.parent = null;
				((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				BindConfig();
				cfgEnableMod.SettingChanged += OnConfigChanged;
				cfgRangeMultiplier.SettingChanged += OnConfigChanged;
				cfgUseAbsoluteRange.SettingChanged += OnConfigChanged;
				cfgAbsoluteRange.SettingChanged += OnConfigChanged;
				cfgApplyVisualForClients.SettingChanged += OnConfigChanged;
				cfgApplyArenaWeapons.SettingChanged += OnConfigChanged;
				cfgApplyStaffItems.SettingChanged += OnConfigChanged;
				cfgStaffRangeMultiplier.SettingChanged += OnConfigChanged;
				cfgStaffUseAbsoluteRange.SettingChanged += OnConfigChanged;
				cfgStaffAbsoluteRange.SettingChanged += OnConfigChanged;
				cfgStaffProjectileSpeedMultiplier.SettingChanged += OnConfigChanged;
				cfgStaffAreaEffectMultiplier.SettingChanged += OnConfigChanged;
				harmony = new Harmony("REPOJP.GunRangeNoLimit");
				harmony.PatchAll(typeof(ItemGunPatches));
				harmony.PatchAll(typeof(ItemGunLaserPatches));
				harmony.PatchAll(typeof(ArenaCartCannonPatches));
				harmony.PatchAll(typeof(ArenaCartLaserPatches));
				PatchStaffTypes();
				Log.LogInfo((object)"GunRangeNoLimit 4.0.2 loaded.");
			}
			catch (Exception ex)
			{
				if (((BaseUnityPlugin)this).Logger != null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Awake\n" + ex));
				}
			}
		}

		private void OnDestroy()
		{
			try
			{
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: OnDestroy\n" + ex));
				}
			}
		}

		private void BindConfig()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Expected O, but got Unknown
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Expected O, but got Unknown
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Expected O, but got Unknown
			cfgEnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, new ConfigDescription("Enable or disable this mod.このMODを有効化または無効化します", (AcceptableValueBase)null, Array.Empty<object>()));
			cfgRangeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Range", "RangeMultiplier", 300f, new ConfigDescription("Multiplier applied to each vanilla weapon range when UseAbsoluteRange is false. Use 1.0 for vanilla range.UseAbsoluteRangeがfalseの場合に各武器のバニラ射程へ適用する倍率です。1.0でバニラ射程です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 10000f), Array.Empty<object>()));
			cfgUseAbsoluteRange = ((BaseUnityPlugin)this).Config.Bind<bool>("Range", "UseAbsoluteRange", false, new ConfigDescription("Use AbsoluteRange instead of multiplying each vanilla range.各武器のバニラ射程倍率ではなくAbsoluteRangeを使用します", (AcceptableValueBase)null, Array.Empty<object>()));
			cfgAbsoluteRange = ((BaseUnityPlugin)this).Config.Bind<float>("Range", "AbsoluteRange", 5000f, new ConfigDescription("Fixed range used by all supported guns when UseAbsoluteRange is true.UseAbsoluteRangeがtrueの場合に対応銃へ使用する固定射程です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 100000f), Array.Empty<object>()));
			cfgApplyVisualForClients = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ApplyVisualForClients", true, new ConfigDescription("When non-host clients also install this mod, extend their local laser, bullet, and staff projectile visuals. Host hit detection still controls gameplay.MOD導入済み参加者のローカルレーザー、弾道、スタッフ系弾表示も延長します。ゲームプレイ命中判定はホスト側が制御します", (AcceptableValueBase)null, Array.Empty<object>()));
			cfgApplyArenaWeapons = ((BaseUnityPlugin)this).Config.Bind<bool>("Arena", "ApplyArenaWeapons", true, new ConfigDescription("Apply the range change to arena cart cannon and arena cart laser weapons.アリーナ系カートキャノンとカートレーザーにも射程変更を適用します", (AcceptableValueBase)null, Array.Empty<object>()));
			cfgApplyStaffItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Staff", "ApplyStaffItems", true, new ConfigDescription("Apply the range change to Torque Staff, Void Staff, Zero Gravity Staff, and Star Wand projectiles.ロールスタッフ、Voidスタッフ、Zero Gravityスタッフ、スターワンドの弾に射程変更を適用します", (AcceptableValueBase)null, Array.Empty<object>()));
			cfgStaffRangeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Staff", "StaffRangeMultiplier", 300f, new ConfigDescription("Multiplier applied to the vanilla staff and Star Wand projectile travel distance when StaffUseAbsoluteRange is false. Vanilla distance is 20.0.StaffUseAbsoluteRangeがfalseの場合にスタッフ系弾とスターワンド弾のバニラ飛距離へ適用する倍率です。バニラ飛距離は20.0です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 10000f), Array.Empty<object>()));
			cfgStaffUseAbsoluteRange = ((BaseUnityPlugin)this).Config.Bind<bool>("Staff", "StaffUseAbsoluteRange", false, new ConfigDescription("Use StaffAbsoluteRange instead of multiplying the vanilla staff and Star Wand projectile travel distance.スタッフ系弾とスターワンド弾のバニラ飛距離倍率ではなくStaffAbsoluteRangeを使用します", (AcceptableValueBase)null, Array.Empty<object>()));
			cfgStaffAbsoluteRange = ((BaseUnityPlugin)this).Config.Bind<float>("Staff", "StaffAbsoluteRange", 5000f, new ConfigDescription("Fixed travel distance used by supported staff and Star Wand projectiles when StaffUseAbsoluteRange is true.StaffUseAbsoluteRangeがtrueの場合に対応スタッフ系弾とスターワンド弾へ使用する固定飛距離です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 100000f), Array.Empty<object>()));
			cfgStaffProjectileSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Staff", "StaffProjectileSpeedMultiplier", 1f, new ConfigDescription("Multiplier applied to supported staff and Star Wand projectile movement speed. Higher values can make collision detection less stable.対応スタッフ系弾とスターワンド弾の移動速度へ適用する倍率です。高すぎる値は衝突判定を不安定にする場合があります", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 10f), Array.Empty<object>()));
			cfgStaffAreaEffectMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Staff", "StaffAreaEffectMultiplier", 1f, new ConfigDescription("Multiplier applied to the area effect collider of supported staff and Star Wand projectiles. Use 1.0 for vanilla effect size.対応スタッフ系弾とスターワンド弾の範囲効果Colliderへ適用する倍率です。1.0でバニラ効果範囲です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 20f), Array.Empty<object>()));
		}

		private void PatchStaffTypes()
		{
			try
			{
				SetupStaffReflection();
				if (slowProjectileType == null)
				{
					if (Log != null)
					{
						Log.LogInfo((object)"Staff projectile patch skipped. SlowProjectile type was not found.");
					}
					return;
				}
				harmony.PatchAll(typeof(SlowProjectileSetSpawnerRpcPatch));
				harmony.PatchAll(typeof(SlowProjectileLaunchRpcPatch));
				harmony.PatchAll(typeof(SlowProjectileAutoDestroyPatch));
				if (semiAreaOfEffectType != null)
				{
					harmony.PatchAll(typeof(SemiAreaOfEffectDoAreaOfEffectPatch));
				}
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: PatchStaffTypes\n" + ex));
				}
			}
		}

		private static void SetupStaffReflection()
		{
			slowProjectileType = AccessTools.TypeByName("SlowProjectile");
			semiAreaOfEffectType = AccessTools.TypeByName("SemiAreaOfEffect");
			itemStaffTorqueType = AccessTools.TypeByName("ItemStaffTorque");
			itemStaffVoidType = AccessTools.TypeByName("ItemStaffVoid");
			itemStaffZeroGravityType = AccessTools.TypeByName("ItemStaffZeroGravity");
			valuableStarWandType = AccessTools.TypeByName("ValuableStarWand");
			photonViewType = AccessTools.TypeByName("Photon.Pun.PhotonView");
			rpcTargetType = AccessTools.TypeByName("Photon.Pun.RpcTarget");
			if (slowProjectileType != null)
			{
				slowProjectileSpeedField = AccessTools.Field(slowProjectileType, "speed");
				slowProjectileSpawnPositionField = AccessTools.Field(slowProjectileType, "spawnPosition");
				slowProjectileMoveDirectionField = AccessTools.Field(slowProjectileType, "moveDirection");
				slowProjectileDestroyedField = AccessTools.Field(slowProjectileType, "destroyed");
				slowProjectileAreaOfEffectField = AccessTools.Field(slowProjectileType, "areaOfEffect");
				slowProjectileSpawnerField = AccessTools.Field(slowProjectileType, "spawner");
				slowProjectileUseExplosionField = AccessTools.Field(slowProjectileType, "useExplosion");
				slowProjectileUseAreaOfEffectField = AccessTools.Field(slowProjectileType, "useAreaOfEffect");
				slowProjectileExplosionMethod = AccessTools.Method(slowProjectileType, "Explosion", (Type[])null, (Type[])null);
				slowProjectileDestroyRpcMethod = AccessTools.Method(slowProjectileType, "DestroyRPC", (Type[])null, (Type[])null);
			}
			if (semiAreaOfEffectType != null)
			{
				semiAreaOfEffectHurtColliderField = AccessTools.Field(semiAreaOfEffectType, "hurtCollider");
				semiAreaOfEffectDoAreaOfEffectMethod = AccessTools.Method(semiAreaOfEffectType, "DoAreaOfEffect", (Type[])null, (Type[])null);
			}
			if (photonViewType != null && rpcTargetType != null)
			{
				photonViewRpcMethod = GetPhotonViewRpcMethod(photonViewType, rpcTargetType);
			}
		}

		private static MethodInfo GetPhotonViewRpcMethod(Type targetPhotonViewType, Type targetRpcTargetType)
		{
			MethodInfo[] methods = targetPhotonViewType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (!(methodInfo.Name != "RPC"))
				{
					ParameterInfo[] parameters = methodInfo.GetParameters();
					if (parameters.Length == 3 && !(parameters[0].ParameterType != typeof(string)) && !(parameters[1].ParameterType != targetRpcTargetType) && !(parameters[2].ParameterType != typeof(object[])))
					{
						return methodInfo;
					}
				}
			}
			return null;
		}

		private static void OnConfigChanged(object sender, EventArgs e)
		{
			ApplyAllExistingItemGuns();
		}

		private static void ApplyAllExistingItemGuns()
		{
			try
			{
				ItemGun[] array = Object.FindObjectsOfType<ItemGun>(true);
				for (int i = 0; i < array.Length; i++)
				{
					ApplyItemGunRange(array[i]);
				}
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: ApplyAllExistingItemGuns\n" + ex));
				}
			}
		}

		private static void ApplyItemGunRange(ItemGun gun)
		{
			if (!((Object)(object)gun == (Object)null))
			{
				int instanceID = ((Object)gun).GetInstanceID();
				if (!originalItemGunRanges.ContainsKey(instanceID))
				{
					originalItemGunRanges[instanceID] = gun.gunRange;
				}
				float num = originalItemGunRanges[instanceID];
				if (!IsEnabled())
				{
					gun.gunRange = num;
				}
				else if (!ShouldApplyOnThisClient())
				{
					gun.gunRange = num;
				}
				else
				{
					gun.gunRange = GetFinalRange(num);
				}
			}
		}

		private static bool IsEnabled()
		{
			return cfgEnableMod != null && cfgEnableMod.Value;
		}

		private static bool IsStaffFeatureEnabled()
		{
			return IsEnabled() && cfgApplyStaffItems != null && cfgApplyStaffItems.Value;
		}

		private static bool ShouldApplyOnThisClient()
		{
			if (!IsEnabled())
			{
				return false;
			}
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			return cfgApplyVisualForClients != null && cfgApplyVisualForClients.Value;
		}

		private static bool ShouldApplyArenaWeapons()
		{
			if (!ShouldApplyOnThisClient())
			{
				return false;
			}
			return cfgApplyArenaWeapons != null && cfgApplyArenaWeapons.Value;
		}

		private static float GetFinalRange(float baseRange)
		{
			if (!IsEnabled())
			{
				return baseRange;
			}
			if (cfgUseAbsoluteRange != null && cfgUseAbsoluteRange.Value)
			{
				return Mathf.Max(0.01f, cfgAbsoluteRange.Value);
			}
			float num = ((cfgRangeMultiplier != null) ? cfgRangeMultiplier.Value : 1f);
			return Mathf.Max(0.01f, baseRange * num);
		}

		private static float GetFinalStaffRange(float baseRange)
		{
			if (!IsStaffFeatureEnabled())
			{
				return baseRange;
			}
			if (cfgStaffUseAbsoluteRange != null && cfgStaffUseAbsoluteRange.Value)
			{
				return Mathf.Max(0.01f, cfgStaffAbsoluteRange.Value);
			}
			float num = ((cfgStaffRangeMultiplier != null) ? cfgStaffRangeMultiplier.Value : 1f);
			return Mathf.Max(0.01f, baseRange * num);
		}

		private static float GetArenaCartCannonRange()
		{
			if (!ShouldApplyArenaWeapons())
			{
				return 25f;
			}
			return GetFinalRange(25f);
		}

		private static float GetArenaCartLaserRange()
		{
			if (!ShouldApplyArenaWeapons())
			{
				return 15f;
			}
			return GetFinalRange(15f);
		}

		private static void RegisterStaffProjectile(object projectile)
		{
			Component val = (Component)((projectile is Component) ? projectile : null);
			if (!((Object)(object)val == (Object)null))
			{
				int instanceID = ((Object)val).GetInstanceID();
				staffProjectileIds.Add(instanceID);
				ApplyStaffProjectileSpeed(projectile);
				ApplyStaffAreaEffectScaleFromProjectile(projectile);
			}
		}

		private static bool IsStaffProjectile(object projectile)
		{
			Component val = (Component)((projectile is Component) ? projectile : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			return staffProjectileIds.Contains(((Object)val).GetInstanceID());
		}

		private static void TryRegisterStaffProjectileFromSpawner(object projectile)
		{
			if (projectile != null && !IsStaffProjectile(projectile))
			{
				GameObject slowProjectileSpawner = GetSlowProjectileSpawner(projectile);
				if (IsStaffSpawner(slowProjectileSpawner))
				{
					RegisterStaffProjectile(projectile);
				}
			}
		}

		private static GameObject GetSlowProjectileSpawner(object projectile)
		{
			if (projectile == null || slowProjectileSpawnerField == null)
			{
				return null;
			}
			object? value = slowProjectileSpawnerField.GetValue(projectile);
			return (GameObject)((value is GameObject) ? value : null);
		}

		private static bool IsStaffSpawner(GameObject spawner)
		{
			if ((Object)(object)spawner == (Object)null)
			{
				return false;
			}
			if (HasComponent(spawner, itemStaffTorqueType))
			{
				return true;
			}
			if (HasComponent(spawner, itemStaffVoidType))
			{
				return true;
			}
			if (HasComponent(spawner, itemStaffZeroGravityType))
			{
				return true;
			}
			if (HasComponent(spawner, valuableStarWandType))
			{
				return true;
			}
			Component[] components = spawner.GetComponents<Component>();
			foreach (Component val in components)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string name = ((object)val).GetType().Name;
				switch (name)
				{
				default:
					if (!(name == "ValuableStarWand"))
					{
						continue;
					}
					break;
				case "ItemStaffTorque":
				case "ItemStaffVoid":
				case "ItemStaffZeroGravity":
					break;
				}
				return true;
			}
			return false;
		}

		private static bool HasComponent(GameObject target, Type componentType)
		{
			if ((Object)(object)target == (Object)null || componentType == null)
			{
				return false;
			}
			return (Object)(object)target.GetComponent(componentType) != (Object)null;
		}

		private static bool ShouldControlStaffProjectileAutoDestroy(object projectile)
		{
			return IsStaffFeatureEnabled() && IsStaffProjectile(projectile);
		}

		private static bool ShouldApplyStaffProjectileVisual(object projectile)
		{
			if (!ShouldControlStaffProjectileAutoDestroy(projectile))
			{
				return false;
			}
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			return cfgApplyVisualForClients != null && cfgApplyVisualForClients.Value;
		}

		private static void ApplyStaffProjectileSpeed(object projectile)
		{
			try
			{
				if (!ShouldApplyStaffProjectileVisual(projectile) || slowProjectileSpeedField == null)
				{
					return;
				}
				Component val = (Component)((projectile is Component) ? projectile : null);
				if (!((Object)(object)val == (Object)null))
				{
					int instanceID = ((Object)val).GetInstanceID();
					float value = Convert.ToSingle(slowProjectileSpeedField.GetValue(projectile));
					if (!originalStaffProjectileSpeeds.ContainsKey(instanceID))
					{
						originalStaffProjectileSpeeds[instanceID] = value;
					}
					float num = ((cfgStaffProjectileSpeedMultiplier != null) ? cfgStaffProjectileSpeedMultiplier.Value : 1f);
					float num2 = Mathf.Max(0.01f, originalStaffProjectileSpeeds[instanceID] * num);
					slowProjectileSpeedField.SetValue(projectile, num2);
				}
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: ApplyStaffProjectileSpeed\n" + ex));
				}
			}
		}

		private static bool HasStaffProjectileReachedRange(object projectile)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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)
			Component val = (Component)((projectile is Component) ? projectile : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (slowProjectileSpawnPositionField == null)
			{
				return false;
			}
			Vector3 val2 = (Vector3)slowProjectileSpawnPositionField.GetValue(projectile);
			float num = Vector3.Distance(val.transform.position, val2);
			return num > GetFinalStaffRange(20f);
		}

		private static Vector3 GetStaffProjectileMoveDirection(object projectile)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Component val = (Component)((projectile is Component) ? projectile : null);
			if ((Object)(object)val == (Object)null)
			{
				return Vector3.forward;
			}
			Vector3 val2 = val.transform.forward;
			if (slowProjectileMoveDirectionField != null)
			{
				val2 = (Vector3)slowProjectileMoveDirectionField.GetValue(projectile);
			}
			if (((Vector3)(ref val2)).sqrMagnitude <= 0.0001f)
			{
				val2 = val.transform.forward;
			}
			if (((Vector3)(ref val2)).sqrMagnitude <= 0.0001f)
			{
				val2 = Vector3.forward;
			}
			return ((Vector3)(ref val2)).normalized;
		}

		private static bool IsStaffProjectileDestroyed(object projectile)
		{
			if (projectile == null)
			{
				return true;
			}
			if (slowProjectileDestroyedField == null)
			{
				return false;
			}
			return Convert.ToBoolean(slowProjectileDestroyedField.GetValue(projectile));
		}

		private static void TriggerStaffProjectileRangeEffect(object projectile)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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)
			try
			{
				Component val = (Component)((projectile is Component) ? projectile : null);
				if ((Object)(object)val == (Object)null || IsStaffProjectileDestroyed(projectile) || !SemiFunc.IsMasterClientOrSingleplayer())
				{
					return;
				}
				Vector3 position = val.transform.position;
				Vector3 staffProjectileMoveDirection = GetStaffProjectileMoveDirection(projectile);
				if (GetBoolField(slowProjectileUseExplosionField, projectile) && slowProjectileExplosionMethod != null)
				{
					slowProjectileExplosionMethod.Invoke(projectile, new object[1] { position });
					return;
				}
				if (GetBoolField(slowProjectileUseAreaOfEffectField, projectile) && slowProjectileAreaOfEffectField != null)
				{
					object value = slowProjectileAreaOfEffectField.GetValue(projectile);
					if (value != null)
					{
						ApplyStaffAreaEffectScale(value);
						InvokeDoAreaOfEffect(value, position, staffProjectileMoveDirection);
					}
				}
				DestroyStaffProjectile(projectile);
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: TriggerStaffProjectileRangeEffect\n" + ex));
				}
			}
		}

		private static bool GetBoolField(FieldInfo field, object instance)
		{
			if (field == null || instance == null)
			{
				return false;
			}
			return Convert.ToBoolean(field.GetValue(instance));
		}

		private static void InvokeDoAreaOfEffect(object areaOfEffect, Vector3 position, Vector3 direction)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (areaOfEffect != null && !(semiAreaOfEffectDoAreaOfEffectMethod == null))
			{
				semiAreaOfEffectDoAreaOfEffectMethod.Invoke(areaOfEffect, new object[2] { position, direction });
			}
		}

		private static void DestroyStaffProjectile(object projectile)
		{
			Component val = (Component)((projectile is Component) ? projectile : null);
			if (!((Object)(object)val == (Object)null) && (!SemiFunc.IsMultiplayer() || !CallPhotonViewRpc(val.gameObject, "DestroyRPC")) && slowProjectileDestroyRpcMethod != null)
			{
				slowProjectileDestroyRpcMethod.Invoke(projectile, null);
			}
		}

		private static bool CallPhotonViewRpc(GameObject targetObject, string rpcName)
		{
			try
			{
				if ((Object)(object)targetObject == (Object)null || photonViewType == null || rpcTargetType == null || photonViewRpcMethod == null)
				{
					return false;
				}
				Component component = targetObject.GetComponent(photonViewType);
				if ((Object)(object)component == (Object)null)
				{
					return false;
				}
				object obj = Enum.Parse(rpcTargetType, "All");
				photonViewRpcMethod.Invoke(component, new object[3]
				{
					rpcName,
					obj,
					new object[0]
				});
				return true;
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: CallPhotonViewRpc\n" + ex));
				}
				return false;
			}
		}

		private static void ApplyStaffAreaEffectScaleFromProjectile(object projectile)
		{
			try
			{
				if (projectile != null && !(slowProjectileAreaOfEffectField == null))
				{
					object value = slowProjectileAreaOfEffectField.GetValue(projectile);
					ApplyStaffAreaEffectScale(value);
				}
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: ApplyStaffAreaEffectScaleFromProjectile\n" + ex));
				}
			}
		}

		private static void ApplyStaffAreaEffectScale(object areaOfEffect)
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (areaOfEffect == null || !IsStaffFeatureEnabled())
				{
					return;
				}
				float num = ((cfgStaffAreaEffectMultiplier != null) ? cfgStaffAreaEffectMultiplier.Value : 1f);
				if (Mathf.Approximately(num, 1f) || semiAreaOfEffectHurtColliderField == null)
				{
					return;
				}
				object? value = semiAreaOfEffectHurtColliderField.GetValue(areaOfEffect);
				Component val = (Component)((value is Component) ? value : null);
				if (!((Object)(object)val == (Object)null))
				{
					Transform transform = val.transform;
					int instanceID = ((Object)transform).GetInstanceID();
					if (!originalAreaEffectHurtColliderScales.ContainsKey(instanceID))
					{
						originalAreaEffectHurtColliderScales[instanceID] = transform.localScale;
					}
					transform.localScale = originalAreaEffectHurtColliderScales[instanceID] * num;
				}
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: ApplyStaffAreaEffectScale\n" + ex));
				}
			}
		}

		private static bool IsFloatConstant(CodeInstruction code, float value)
		{
			if (code == null || code.opcode != OpCodes.Ldc_R4)
			{
				return false;
			}
			if (!(code.operand is float))
			{
				return false;
			}
			float num = (float)code.operand;
			return Math.Abs(num - value) < 0.001f;
		}

		[IteratorStateMachine(typeof(<ReplaceFloatConstant>d__79))]
		private static IEnumerable<CodeInstruction> ReplaceFloatConstant(IEnumerable<CodeInstruction> instructions, float targetValue, MethodInfo replacementMethod)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ReplaceFloatConstant>d__79(-2)
			{
				<>3__instructions = instructions,
				<>3__targetValue = targetValue,
				<>3__replacementMethod = replacementMethod
			};
		}

		private static void SlowProjectile_SetSpawnerRPC_Postfix(object __instance)
		{
			try
			{
				if (IsStaffFeatureEnabled())
				{
					TryRegisterStaffProjectileFromSpawner(__instance);
				}
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: SlowProjectile_SetSpawnerRPC_Postfix\n" + ex));
				}
			}
		}

		private static void SlowProjectile_LaunchRPC_Postfix(object __instance)
		{
			try
			{
				if (IsStaffFeatureEnabled())
				{
					TryRegisterStaffProjectileFromSpawner(__instance);
					ApplyStaffProjectileSpeed(__instance);
				}
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: SlowProjectile_LaunchRPC_Postfix\n" + ex));
				}
			}
		}

		private static bool SlowProjectile_AutoDestroy_Prefix(object __instance)
		{
			try
			{
				if (!ShouldControlStaffProjectileAutoDestroy(__instance))
				{
					return true;
				}
				if (!SemiFunc.IsMasterClientOrSingleplayer())
				{
					return false;
				}
				if (HasStaffProjectileReachedRange(__instance))
				{
					TriggerStaffProjectileRangeEffect(__instance);
				}
				return false;
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: SlowProjectile_AutoDestroy_Prefix\n" + ex));
				}
				return true;
			}
		}

		private static void SemiAreaOfEffect_DoAreaOfEffect_Prefix(object __instance)
		{
			try
			{
				Component val = (Component)((__instance is Component) ? __instance : null);
				if (!((Object)(object)val == (Object)null) && !(slowProjectileType == null))
				{
					Component componentInParent = val.GetComponentInParent(slowProjectileType);
					if (IsStaffProjectile(componentInParent))
					{
						ApplyStaffAreaEffectScale(__instance);
					}
				}
			}
			catch (Exception ex)
			{
				if (Log != null)
				{
					Log.LogError((object)("Failure: SemiAreaOfEffect_DoAreaOfEffect_Prefix\n" + ex));
				}
			}
		}
	}
}