BepInEx\plugins\PPR\AnimationSpeedManager.dll

Decompiled 6 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AnimationSpeedManager")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AnimationSpeedManager")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("B3A6D52C-449A-4665-9FD0-BB48C8CF2CDF")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class AnimationSpeedManager
{
	public delegate double Handler(Character character, double speed);

	private static readonly Harmony harmony = new Harmony("AnimationSpeedManager");

	private static bool hasMarkerPatch = false;

	private static readonly MethodInfo method = AccessTools.DeclaredMethod(typeof(CharacterAnimEvent), "CustomFixedUpdate", (Type[])null, (Type[])null);

	private static int index = 0;

	private static bool changed = false;

	private static Handler[][] handlers = Array.Empty<Handler[]>();

	private static readonly Dictionary<int, List<Handler>> handlersPriorities = new Dictionary<int, List<Handler>>();

	[PublicAPI]
	public static void Add(Handler handler, int priority = 400)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		if (!hasMarkerPatch)
		{
			harmony.Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(AnimationSpeedManager), "markerPatch", (Type[])null, (Type[])null)), (HarmonyMethod)null);
			hasMarkerPatch = true;
		}
		if (!handlersPriorities.TryGetValue(priority, out List<Handler> value))
		{
			handlersPriorities.Add(priority, value = new List<Handler>());
			harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(AnimationSpeedManager), "wrapper", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		value.Add(handler);
		handlers = (from kv in handlersPriorities
			orderby kv.Key
			select kv.Value.ToArray()).ToArray();
	}

	private static void wrapper(Character ___m_character, Animator ___m_animator)
	{
		Character ___m_character2 = ___m_character;
		double num = (double)___m_animator.speed * 10000000.0 % 100.0;
		if ((!(num > 10.0) || !(num < 30.0)) && !(___m_animator.speed <= 0.001f))
		{
			double num2 = ___m_animator.speed;
			double num3 = handlers[index++].Aggregate(num2, (double current, Handler handler) => handler(___m_character2, current));
			if (num3 != num2)
			{
				___m_animator.speed = (float)(num3 - num3 % 1E-05);
				changed = true;
			}
		}
	}

	private static void markerPatch(Animator ___m_animator)
	{
		if (changed)
		{
			double num = (double)___m_animator.speed * 10000000.0 % 100.0;
			if ((num < 10.0 || num > 30.0) ? true : false)
			{
				___m_animator.speed += 1.9E-06f;
			}
			changed = false;
		}
		index = 0;
	}
}

BepInEx\plugins\PPR\PPR.dll

Decompiled 6 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
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: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PPR
{
	internal static class PPRAccess
	{
		public static ItemData GetCurrentWeapon(Humanoid h)
		{
			return Traverse.Create((object)h).Method("GetCurrentWeapon", Array.Empty<object>()).GetValue<ItemData>();
		}

		public static ItemData GetCurrentBlocker(Humanoid h)
		{
			return Traverse.Create((object)h).Method("GetCurrentBlocker", Array.Empty<object>()).GetValue<ItemData>();
		}

		public static bool HaveSecondaryAttack(ItemData item)
		{
			return Traverse.Create((object)item).Method("HaveSecondaryAttack", Array.Empty<object>()).GetValue<bool>();
		}

		public static bool HaveStamina(Character c, float amount)
		{
			return Traverse.Create((object)c).Method("HaveStamina", new Type[1] { typeof(float) }, new object[1] { amount }).GetValue<bool>();
		}

		public static bool IsStaggering(Character c)
		{
			return Traverse.Create((object)c).Method("IsStaggering", Array.Empty<object>()).GetValue<bool>();
		}

		public static bool InAttack(Character c)
		{
			return Traverse.Create((object)c).Method("InAttack", Array.Empty<object>()).GetValue<bool>();
		}

		public static bool CanMove(Character c)
		{
			return Traverse.Create((object)c).Method("CanMove", Array.Empty<object>()).GetValue<bool>();
		}
	}
	[HarmonyPatch(typeof(Humanoid), "StartAttack")]
	public static class PPRStartAttackPatch
	{
		[HarmonyPrefix]
		public static void Prefix(Humanoid __instance, bool secondaryAttack)
		{
			try
			{
				if (!PPRConfig.Enable.Value || !secondaryAttack)
				{
					return;
				}
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && PPRState.IsParryWindowActive(val))
				{
					ItemData currentWeapon = PPRAccess.GetCurrentWeapon(__instance);
					if (currentWeapon == null || !PPRAccess.HaveSecondaryAttack(currentWeapon))
					{
						Plugin.Log.LogWarning((object)"[PPR] 카운터 실패 - 현재 무기에 특수 공격 없음");
						PPRState.ConsumeParry(val);
					}
					else
					{
						PPRState.ConsumeParry(val);
						PPRState.ActivateCounterSpeed(val);
						Plugin.Log.LogInfo((object)$"[PPR] 카운터 발동! InAttack={PPRAccess.InAttack((Character)(object)__instance)}, CanMove={PPRAccess.CanMove((Character)(object)__instance)}");
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[PPR] StartAttackPatch 오류: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(Player), "Update")]
	public static class PPRTickPatch
	{
		[HarmonyPostfix]
		public static void Postfix(Player __instance)
		{
			try
			{
				if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
				{
					PPRState.Tick(__instance, Time.deltaTime);
					PPRState.TickCounterSpeed(__instance, PPRAccess.InAttack((Character)(object)__instance));
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[PPR] TickPatch 오류: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "BlockAttack")]
	public static class PPRBlockPatch
	{
		[HarmonyPostfix]
		public static void Postfix(Humanoid __instance, HitData hit, Character attacker, bool __result, float ___m_blockTimer)
		{
			//IL_0068: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Invalid comparison between Unknown and I4
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Invalid comparison between Unknown and I4
			try
			{
				if (!__result || !PPRConfig.Enable.Value)
				{
					return;
				}
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
				{
					return;
				}
				ItemData currentWeapon = PPRAccess.GetCurrentWeapon(__instance);
				if (currentWeapon == null)
				{
					return;
				}
				ItemType itemType = currentWeapon.m_shared.m_itemType;
				if (((int)itemType == 3 || (int)itemType == 14 || (int)itemType == 22) && PPRAccess.HaveSecondaryAttack(currentWeapon))
				{
					ItemData currentBlocker = PPRAccess.GetCurrentBlocker(__instance);
					if (currentBlocker != null && !(currentBlocker.m_shared.m_timedBlockBonus <= 1f) && PPRAccess.HaveStamina((Character)(object)__instance, 0f) && !PPRAccess.IsStaggering((Character)(object)__instance) && !(___m_blockTimer < 0f) && !(___m_blockTimer >= PPRConfig.ParryWindow.Value))
					{
						PPRState.ActivateParry(val);
						PPRState.SpawnParryVFX(val);
						Plugin.Log.LogInfo((object)$"[PPR] 패링 감지 (blockTimer={___m_blockTimer:F3}s)");
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[PPR] BlockPatch 오류: " + ex.Message));
			}
		}
	}
	public static class PPRConfig
	{
		private const string SEC = "Perfect Parry";

		private const string SEC_DMG = "Perfect Parry - Damage Reduction";

		private const string SEC_VFX = "Perfect Parry - Effect";

		public static ConfigEntry<bool> Enable;

		public static ConfigEntry<float> ParryWindow;

		public static ConfigEntry<float> CounterWindow;

		public static ConfigEntry<float> CounterSpeedMultiplier;

		public static ConfigEntry<bool> DamageReductionEnabled;

		public static ConfigEntry<float> DamageReductionPercent;

		public static ConfigEntry<bool> VFXEnabled;

		public static ConfigEntry<string> VFXPrefab;

		public static ConfigEntry<float> VFXOffsetX;

		public static ConfigEntry<float> VFXOffsetY;

		public static ConfigEntry<float> VFXOffsetZ;

		public static void Init(ConfigFile cfg)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Expected O, but got Unknown
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			Enable = cfg.Bind<bool>("Perfect Parry", "(Enable) Perfect Parry", true, "Enable or disable the Perfect Parry feature.");
			ParryWindow = cfg.Bind<float>("Perfect Parry", "(Parry) Detection Window (sec)", 0.1f, new ConfigDescription("Time window to register a perfect parry. Must be shorter than the base perfect block window (0.25s).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.24f), Array.Empty<object>()));
			CounterWindow = cfg.Bind<float>("Perfect Parry", "(Counter) Input Window (sec)", 0.6f, new ConfigDescription("Time after a successful parry during which you can press the secondary attack key to trigger a counter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>()));
			CounterSpeedMultiplier = cfg.Bind<float>("Perfect Parry", "(Counter) Animation Speed Multiplier", 2.5f, new ConfigDescription("Animation speed multiplier for the counter special attack. 2.5 = 2.5x faster.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
			DamageReductionEnabled = cfg.Bind<bool>("Perfect Parry - Damage Reduction", "(Enable) Damage Reduction", true, "Reduce incoming damage during the counter window after a successful parry.");
			DamageReductionPercent = cfg.Bind<float>("Perfect Parry - Damage Reduction", "(Damage Reduction) Reduction Rate (%)", 50f, new ConfigDescription("Damage reduction percentage during the counter window. 50 = 50% less damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			VFXEnabled = cfg.Bind<bool>("Perfect Parry - Effect", "(Enable) Head Effect", true, "Show a VFX above the player's head on successful parry.");
			VFXPrefab = cfg.Bind<string>("Perfect Parry - Effect", "(Effect) VFX Name", "vfx_blocked", "Name of the VFX prefab to display. Must be a valid ZNetScene prefab name.");
			VFXOffsetX = cfg.Bind<float>("Perfect Parry - Effect", "(Effect) Offset X", 0f, new ConfigDescription("Horizontal offset (left/right) relative to the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-5f, 5f), Array.Empty<object>()));
			VFXOffsetY = cfg.Bind<float>("Perfect Parry - Effect", "(Effect) Offset Y", 2.5f, new ConfigDescription("Vertical offset (height) relative to the player. Default 2.5 = above head.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 8f), Array.Empty<object>()));
			VFXOffsetZ = cfg.Bind<float>("Perfect Parry - Effect", "(Effect) Offset Z", 0f, new ConfigDescription("Depth offset (forward/back) relative to the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-5f, 5f), Array.Empty<object>()));
		}
	}
	[HarmonyPatch(typeof(Character), "ApplyDamage")]
	public static class PPRDamagePatch
	{
		[HarmonyPrefix]
		public static void Prefix(Character __instance, HitData hit)
		{
			try
			{
				if (PPRConfig.Enable.Value && PPRConfig.DamageReductionEnabled.Value)
				{
					Player val = (Player)(object)((__instance is Player) ? __instance : null);
					if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && PPRState.IsParryWindowActive(val) && hit != null)
					{
						float num = 1f - PPRConfig.DamageReductionPercent.Value / 100f;
						((DamageTypes)(ref hit.m_damage)).Modify(num);
						Plugin.Log.LogInfo((object)$"[PPR] 데미지 감소 적용 ({PPRConfig.DamageReductionPercent.Value}%)");
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[PPR] DamagePatch 오류: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(Game), "Awake")]
	public static class PPRSpeedRegistrar
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Handler <>9__1_0;

			internal double <Postfix>b__1_0(Character character, double speed)
			{
				try
				{
					if (!PPRConfig.Enable.Value)
					{
						return speed;
					}
					Player val = (Player)(object)((character is Player) ? character : null);
					if (val == null)
					{
						return speed;
					}
					if (!PPRState.IsCounterSpeedActive(val))
					{
						return speed;
					}
					if (!PPRAccess.InAttack((Character)(object)val))
					{
						return speed;
					}
					return speed * (double)PPRConfig.CounterSpeedMultiplier.Value;
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("[PPR] SpeedCallback 오류: " + ex.Message));
					return speed;
				}
			}
		}

		private static bool _registered;

		[HarmonyPostfix]
		public static void Postfix()
		{
			//IL_0026: 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_0031: Expected O, but got Unknown
			if (_registered)
			{
				return;
			}
			_registered = true;
			object obj = <>c.<>9__1_0;
			if (obj == null)
			{
				Handler val = delegate(Character character, double speed)
				{
					try
					{
						if (!PPRConfig.Enable.Value)
						{
							return speed;
						}
						Player val2 = (Player)(object)((character is Player) ? character : null);
						if (val2 == null)
						{
							return speed;
						}
						if (!PPRState.IsCounterSpeedActive(val2))
						{
							return speed;
						}
						if (!PPRAccess.InAttack((Character)(object)val2))
						{
							return speed;
						}
						return speed * (double)PPRConfig.CounterSpeedMultiplier.Value;
					}
					catch (Exception ex)
					{
						Plugin.Log.LogError((object)("[PPR] SpeedCallback 오류: " + ex.Message));
						return speed;
					}
				};
				<>c.<>9__1_0 = val;
				obj = (object)val;
			}
			AnimationSpeedManager.Add((Handler)obj, 400);
			Plugin.Log.LogInfo((object)"[PPR] AnimationSpeedManager 콜백 등록 완료.");
		}
	}
	public static class PPRState
	{
		private static readonly Dictionary<Player, float> _counterWindow = new Dictionary<Player, float>();

		private static readonly HashSet<Player> _speedActive = new HashSet<Player>();

		private static readonly Dictionary<Player, bool> _prevInAttack = new Dictionary<Player, bool>();

		private static readonly Dictionary<Player, GameObject> _parryVFX = new Dictionary<Player, GameObject>();

		public static void ActivateParry(Player player)
		{
			_counterWindow[player] = PPRConfig.CounterWindow.Value;
			Plugin.Log.LogInfo((object)"[PPR] 퍼펙트 패링 성공!");
		}

		public static bool IsParryWindowActive(Player player)
		{
			float value;
			return _counterWindow.TryGetValue(player, out value) && value > 0f;
		}

		public static void ConsumeParry(Player player)
		{
			_counterWindow[player] = 0f;
			DestroyParryVFX(player);
		}

		public static void Tick(Player player, float dt)
		{
			if (_counterWindow.TryGetValue(player, out var value) && !(value <= 0f))
			{
				float num = Mathf.Max(0f, value - dt);
				_counterWindow[player] = num;
				if (num <= 0f)
				{
					DestroyParryVFX(player);
				}
			}
		}

		public static void ActivateCounterSpeed(Player player)
		{
			_speedActive.Add(player);
			_prevInAttack[player] = false;
		}

		public static bool IsCounterSpeedActive(Player player)
		{
			return _speedActive.Contains(player);
		}

		public static void TickCounterSpeed(Player player, bool isInAttack)
		{
			bool value;
			if (!_speedActive.Contains(player))
			{
				_prevInAttack.Remove(player);
			}
			else if (_prevInAttack.TryGetValue(player, out value) && value && !isInAttack)
			{
				DeactivateCounterSpeed(player);
			}
			else
			{
				_prevInAttack[player] = isInAttack;
			}
		}

		public static void DeactivateCounterSpeed(Player player)
		{
			_speedActive.Remove(player);
			_prevInAttack.Remove(player);
			Plugin.Log.LogInfo((object)"[PPR] 카운터 속도 해제");
		}

		public static void SpawnParryVFX(Player player)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			DestroyParryVFX(player);
			if (!PPRConfig.VFXEnabled.Value)
			{
				return;
			}
			string value = PPRConfig.VFXPrefab.Value;
			if (string.IsNullOrEmpty(value) || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(value);
			if ((Object)(object)prefab == (Object)null)
			{
				Plugin.Log.LogWarning((object)("[PPR] VFX 프리팹 없음: " + value));
				return;
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(PPRConfig.VFXOffsetX.Value, PPRConfig.VFXOffsetY.Value, PPRConfig.VFXOffsetZ.Value);
			GameObject val2 = Object.Instantiate<GameObject>(prefab, ((Component)player).transform.position + val, Quaternion.identity);
			val2.transform.SetParent(((Component)player).transform, false);
			val2.transform.localPosition = val;
			ZNetView[] componentsInChildren = val2.GetComponentsInChildren<ZNetView>(true);
			foreach (ZNetView val3 in componentsInChildren)
			{
				Object.Destroy((Object)(object)val3);
			}
			ZSyncTransform[] componentsInChildren2 = val2.GetComponentsInChildren<ZSyncTransform>(true);
			foreach (ZSyncTransform val4 in componentsInChildren2)
			{
				Object.Destroy((Object)(object)val4);
			}
			_parryVFX[player] = val2;
			Plugin.Log.LogInfo((object)("[PPR] VFX 스폰: " + value));
		}

		public static void DestroyParryVFX(Player player)
		{
			if (_parryVFX.TryGetValue(player, out var value) && (Object)(object)value != (Object)null)
			{
				Object.Destroy((Object)(object)value);
			}
			_parryVFX.Remove(player);
		}
	}
	[BepInPlugin("com.KorCaptain.PPR", "PPR", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.KorCaptain.PPR";

		public const string PluginName = "PPR";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		private readonly Harmony _harmony = new Harmony("com.KorCaptain.PPR");

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			PPRConfig.Init(((BaseUnityPlugin)this).Config);
			_harmony.PatchAll();
			Log.LogInfo((object)"PPR v1.0.0 loaded.");
		}
	}
}