using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using EWC.CustomWeapon;
using FireRateFPSFix.Dependencies;
using FireRateFPSFix.FireState;
using GTFO.API;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("FireRateFPSFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d79e399a2d6ef35de13a52cefe1208669b9727d1")]
[assembly: AssemblyProduct("FireRateFPSFix")]
[assembly: AssemblyTitle("FireRateFPSFix")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
}
}
}
namespace FireRateFPSFix
{
[BepInPlugin("Dinorush.FireRateFPSFix", "FireRateFPSFix", "1.0.3")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal sealed class EntryPoint : BasePlugin
{
public const string MODNAME = "FireRateFPSFix";
public override void Load()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
new Harmony("FireRateFPSFix").PatchAll();
LevelAPI.OnEnterLevel += LevelAPI_OnEnterLevel;
((BasePlugin)this).Log.LogMessage((object)"Loaded FireRateFPSFix");
}
private void LevelAPI_OnEnterLevel()
{
FireStateManager.Cleanup();
}
}
}
namespace FireRateFPSFix.Utils
{
internal static class DinoLogger
{
private static ManualLogSource logger = Logger.CreateLogSource("FireRateFPSFix");
public static void Log(string format, params object[] args)
{
Log(string.Format(format, args));
}
public static void Log(string str)
{
if (logger != null)
{
logger.Log((LogLevel)8, (object)str);
}
}
public static void Warning(string format, params object[] args)
{
Warning(string.Format(format, args));
}
public static void Warning(string str)
{
if (logger != null)
{
logger.Log((LogLevel)4, (object)str);
}
}
public static void Error(string format, params object[] args)
{
Error(string.Format(format, args));
}
public static void Error(string str)
{
if (logger != null)
{
logger.Log((LogLevel)2, (object)str);
}
}
public static void Debug(string format, params object[] args)
{
Debug(string.Format(format, args));
}
public static void Debug(string str)
{
if (logger != null)
{
logger.Log((LogLevel)32, (object)str);
}
}
}
}
namespace FireRateFPSFix.Patches
{
[HarmonyPatch]
internal static class WeaponFirePatch
{
[HarmonyPatch(typeof(BWA_Burst), "OnStartFiring")]
[HarmonyPatch(typeof(BWA_Auto), "OnStartFiring")]
[HarmonyPatch(typeof(BulletWeaponArchetype), "OnStartFiring")]
[HarmonyWrapSafe]
[HarmonyPostfix]
[HarmonyBefore(new string[] { "Dinorush.ExtraWeaponCustomization" })]
private static void StartFiringCallback(BulletWeaponArchetype __instance)
{
FireStateManager.GetUpdater(__instance.m_weapon).UpdateStartFiring();
}
[HarmonyPatch(typeof(BulletWeaponArchetype), "PostFireCheck")]
[HarmonyWrapSafe]
[HarmonyPostfix]
[HarmonyBefore(new string[] { "Dinorush.ExtraWeaponCustomization" })]
private static void PostFireCallback(BulletWeaponArchetype __instance)
{
FireStateUpdater updater = FireStateManager.GetUpdater(__instance.m_weapon);
if (__instance.m_firing)
{
updater.UpdateFired();
}
}
[HarmonyPatch(typeof(BulletWeaponArchetype), "PostFireCheck")]
[HarmonyWrapSafe]
[HarmonyPostfix]
[HarmonyAfter(new string[] { "Dinorush.ExtraWeaponCustomization" })]
private static void PostFireCallback_AfterEWC(BulletWeaponArchetype __instance)
{
FireStateManager.GetUpdater(__instance.m_weapon).UpdateFireTime();
}
}
}
namespace FireRateFPSFix.FireState
{
public static class FireStateManager
{
private static readonly Dictionary<IntPtr, FireStateUpdater> _updaters = new Dictionary<IntPtr, FireStateUpdater>();
public static FireStateUpdater GetUpdater(BulletWeapon weapon)
{
if (_updaters.TryGetValue(((Il2CppObjectBase)weapon).Pointer, out FireStateUpdater value))
{
return value;
}
return _updaters[((Il2CppObjectBase)weapon).Pointer] = new FireStateUpdater(weapon);
}
public static void Cleanup()
{
KeyValuePair<IntPtr, FireStateUpdater>[] array = _updaters.Where<KeyValuePair<IntPtr, FireStateUpdater>>((KeyValuePair<IntPtr, FireStateUpdater> kv) => !kv.Value.IsValid).ToList().ToArray();
foreach (KeyValuePair<IntPtr, FireStateUpdater> keyValuePair in array)
{
_updaters.Remove(keyValuePair.Key);
}
}
}
public sealed class FireStateUpdater
{
private readonly BulletWeapon _weapon;
private BulletWeaponArchetype _archetype;
private float _shotDelay;
private float _burstDelay;
private float _cooldownDelay;
private IntPtr _archetypePtr;
private float _timeBuffer;
private float _lastFireTime;
public bool IsValid => (Object)(object)_weapon != (Object)null;
public FireStateUpdater(BulletWeapon weapon)
{
_weapon = weapon;
_archetype = _weapon.m_archeType;
_shotDelay = _archetype.ShotDelay();
_burstDelay = _archetype.BurstDelay();
_cooldownDelay = _archetype.CooldownDelay();
_archetypePtr = ((Il2CppObjectBase)_archetype).Pointer;
}
private void UpdateArchetype()
{
BulletWeaponArchetype archeType = _weapon.m_archeType;
if (!(_archetypePtr == ((Il2CppObjectBase)archeType).Pointer))
{
_archetype = archeType;
_shotDelay = _archetype.ShotDelay();
_burstDelay = _archetype.BurstDelay();
_cooldownDelay = _archetype.CooldownDelay();
_archetypePtr = ((Il2CppObjectBase)_archetype).Pointer;
_timeBuffer = 0f;
_lastFireTime = 0f;
}
}
private float GetCooldownDelay()
{
return EWCWrapper.GetCooldownDelay(_weapon, _cooldownDelay);
}
private float GetBurstDelay()
{
return EWCWrapper.GetBurstDelay(_weapon, _burstDelay);
}
private float GetShotDelay()
{
return EWCWrapper.GetShotDelay(_weapon, _shotDelay);
}
public void UpdateStartFiring()
{
UpdateArchetype();
float nextBurstTimer = _archetype.m_nextBurstTimer;
float time = Clock.Time;
if (nextBurstTimer + Clock.Delta >= time)
{
_timeBuffer += time - nextBurstTimer;
}
else
{
_timeBuffer = 0f;
}
_lastFireTime = 0f;
}
public void UpdateFired()
{
UpdateArchetype();
float time = Clock.Time;
if (_lastFireTime != 0f)
{
_timeBuffer += time - _lastFireTime - GetShotDelay();
}
_lastFireTime = time;
}
public void UpdateFireTime()
{
UpdateArchetype();
if (_archetype.m_firing)
{
BulletWeaponArchetype archetype = _archetype;
archetype.m_nextShotTimer -= _timeBuffer;
return;
}
float num = (_archetype.HasCooldown ? GetCooldownDelay() : GetBurstDelay());
_archetype.m_nextBurstTimer = Clock.Time - _timeBuffer + num;
_archetype.m_nextShotTimer = Clock.Time - _timeBuffer + GetShotDelay();
_timeBuffer -= Math.Min(_timeBuffer, num);
}
}
}
namespace FireRateFPSFix.Dependencies
{
internal static class EWCWrapper
{
public const string PLUGIN_GUID = "Dinorush.ExtraWeaponCustomization";
public static readonly bool hasEWC;
static EWCWrapper()
{
hasEWC = ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("Dinorush.ExtraWeaponCustomization");
}
public static float GetBurstDelay(BulletWeapon weapon, float burstDelay)
{
if (!hasEWC)
{
return burstDelay;
}
return GetBurstDelay_Internal(weapon, burstDelay);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static float GetBurstDelay_Internal(BulletWeapon weapon, float burstDelay)
{
CustomWeaponComponent component = ((Component)weapon).GetComponent<CustomWeaponComponent>();
if (!((Object)(object)component != (Object)null))
{
return burstDelay;
}
return component.CurrentBurstDelay;
}
public static float GetShotDelay(BulletWeapon weapon, float shotDelay)
{
if (!hasEWC)
{
return shotDelay;
}
return GetShotDelay_Internal(weapon, shotDelay);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static float GetShotDelay_Internal(BulletWeapon weapon, float shotDelay)
{
CustomWeaponComponent component = ((Component)weapon).GetComponent<CustomWeaponComponent>();
if (!((Object)(object)component != (Object)null))
{
return shotDelay;
}
return 1f / component.CurrentFireRate;
}
public static float GetCooldownDelay(BulletWeapon weapon, float cooldownDelay)
{
if (!hasEWC)
{
return cooldownDelay;
}
return GetCooldownDelay_Internal(weapon, cooldownDelay);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static float GetCooldownDelay_Internal(BulletWeapon weapon, float cooldownDelay)
{
CustomWeaponComponent component = ((Component)weapon).GetComponent<CustomWeaponComponent>();
if (!((Object)(object)component != (Object)null))
{
return cooldownDelay;
}
return 1f / component.CurrentCooldownDelay;
}
}
}