Decompiled source of FastCosmeticGacha v4.0.0

FastCosmeticGacha.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
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.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Release")]
[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.FastCosmeticGacha
{
	[BepInPlugin("REPOJP.FastCosmeticGacha", "FastCosmeticGacha", "1.1.0")]
	public class FastCosmeticGachaPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "REPOJP.FastCosmeticGacha";

		public const string PluginName = "FastCosmeticGacha";

		public const string PluginVersion = "1.1.0";

		internal static ManualLogSource Log;

		private Harmony harmony;

		internal static ConfigEntry<bool> Enable;

		internal static ConfigEntry<bool> ShowDebugLog;

		internal static ConfigEntry<FastGachaSpeedMode> SpeedMode;

		internal static ConfigEntry<float> AnimatorSpeedMultiplier;

		internal static ConfigEntry<float> StateTimerMultiplier;

		internal static ConfigEntry<bool> SkipTokenOutro;

		internal static ConfigEntry<bool> SkipSpinWait;

		internal static ConfigEntry<bool> SkipSEWait;

		internal static ConfigEntry<bool> SkipConfettiWait;

		internal static ConfigEntry<bool> InstantResult;

		internal static ConfigEntry<float> CosmeticResultDisplaySeconds;

		internal static ConfigEntry<float> CurrencyResultDisplaySeconds;

		internal static ConfigEntry<float> ReturnToIdleSeconds;

		internal static ConfigEntry<bool> AccelerateAuthoritativeStateWhenHost;

		internal static ConfigEntry<float> MinimumStateSeconds;

		internal static ConfigEntry<bool> ResetAnimatorSpeedOnIdle;

		internal static ConfigEntry<bool> DoNotSkipRewardSetState;

		internal static ConfigEntry<bool> TurboMode;

		internal static ConfigEntry<bool> AllowQueuedMultiUse;

		internal static ConfigEntry<bool> QueueLocalPresses;

		internal static ConfigEntry<bool> QueueRemoteRequests;

		internal static ConfigEntry<int> MaxQueueSize;

		internal static ConfigEntry<int> MaxQueuedRequestsPerPlayer;

		internal static ConfigEntry<float> QueueProcessDelaySeconds;

		internal static ConfigEntry<float> QueueInteractDistance;

		internal static ConfigEntry<bool> AllowRapidPress;

		internal static ConfigEntry<float> RapidPressCooldownSeconds;

		private void Awake()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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();
				GameReflection.Initialize();
				harmony = new Harmony("REPOJP.FastCosmeticGacha");
				PatchGameMethod("CosmeticShopMachine", "Update", typeof(MachineUpdateHook).GetMethod("Prefix", BindingFlags.Static | BindingFlags.NonPublic), typeof(MachineUpdateHook).GetMethod("Postfix", BindingFlags.Static | BindingFlags.NonPublic));
				PatchGameMethod("CosmeticShopMachine", "UpdateStateRPC", null, typeof(StateRpcHook).GetMethod("Postfix", BindingFlags.Static | BindingFlags.NonPublic));
				PatchGameMethod("CosmeticShopMachine", "ScreenSpinLogic", null, typeof(ScreenSpinHook).GetMethod("Postfix", BindingFlags.Static | BindingFlags.NonPublic));
				PatchGameMethod("CosmeticShopMachine", "InteractClientRPC", typeof(InteractClientRpcHook).GetMethod("Prefix", BindingFlags.Static | BindingFlags.NonPublic), null);
				PatchGameMethod("CosmeticShopMachine", "RewardSet", null, typeof(RewardSetHook).GetMethod("Postfix", BindingFlags.Static | BindingFlags.NonPublic));
				PatchGameMethod("CosmeticShopMachineAnimator", "Update", null, typeof(AnimatorUpdateHook).GetMethod("Postfix", BindingFlags.Static | BindingFlags.NonPublic));
				PatchGameMethod("CosmeticShopMachineConfetti", "Set", null, typeof(ConfettiSetHook).GetMethod("Postfix", BindingFlags.Static | BindingFlags.NonPublic));
				WriteDebugLog("Loaded");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Awake\n" + ex));
			}
		}

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

		private void PatchGameMethod(string targetTypeName, string targetMethodName, MethodInfo prefixMethod, MethodInfo postfixMethod)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (prefixMethod == null && postfixMethod == null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Patch method not found - " + targetTypeName + "." + targetMethodName));
					return;
				}
				Type type = AccessTools.TypeByName(targetTypeName);
				if (type == null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Target type not found - " + targetTypeName));
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(type, targetMethodName, (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Target method not found - " + targetTypeName + "." + targetMethodName));
					return;
				}
				HarmonyMethod val = ((!(prefixMethod != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(prefixMethod));
				HarmonyMethod val2 = ((!(postfixMethod != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(postfixMethod));
				harmony.Patch((MethodBase)methodInfo, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				WriteDebugLog("Patched: " + targetTypeName + "." + targetMethodName);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failure: PatchGameMethod " + targetTypeName + "." + targetMethodName + "\n" + ex));
			}
		}

		private void BindConfig()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Expected O, but got Unknown
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Expected O, but got Unknown
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Expected O, but got Unknown
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Expected O, but got Unknown
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Expected O, but got Unknown
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Expected O, but got Unknown
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Expected O, but got Unknown
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Expected O, but got Unknown
			Enable = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable", true, "Enable this mod.このMODを有効化");
			ShowDebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowDebugLog", false, "Show debug logs.デバッグログを表示");
			SpeedMode = ((BaseUnityPlugin)this).Config.Bind<FastGachaSpeedMode>("Speed", "SpeedMode", FastGachaSpeedMode.Fast, "Animation speed mode.演出速度モード");
			AnimatorSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Speed", "AnimatorSpeedMultiplier", 3f, new ConfigDescription("Animator speed multiplier used by Fast mode. Fastモードで使用するAnimator速度倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
			StateTimerMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Speed", "StateTimerMultiplier", 0.35f, new ConfigDescription("State timer multiplier used by Fast mode. Fastモードで使用するState待機時間倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>()));
			SkipTokenOutro = ((BaseUnityPlugin)this).Config.Bind<bool>("Skip", "SkipTokenOutro", true, "Skip most of the token outro wait.トークン排出演出の待機をほぼ短縮");
			SkipSpinWait = ((BaseUnityPlugin)this).Config.Bind<bool>("Skip", "SkipSpinWait", true, "Skip screen spin wait after token impact.トークン衝突後の画面回転待機を短縮");
			SkipSEWait = ((BaseUnityPlugin)this).Config.Bind<bool>("Skip", "SkipSEWait", true, "Shorten waits that depend on animation or sound events.演出やSEイベント由来の待機を短縮");
			SkipConfettiWait = ((BaseUnityPlugin)this).Config.Bind<bool>("Skip", "SkipConfettiWait", false, "Skip most of the confetti display time.コンフェッティ表示時間をほぼ短縮");
			InstantResult = ((BaseUnityPlugin)this).Config.Bind<bool>("Skip", "InstantResult", false, "Force minimum result flow while keeping reward confirmation.報酬確定処理を残して最短化");
			CosmeticResultDisplaySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Result", "CosmeticResultDisplaySeconds", 1f, new ConfigDescription("Cosmetic result frame display seconds.コスメ報酬フレーム表示秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 10f), Array.Empty<object>()));
			CurrencyResultDisplaySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Result", "CurrencyResultDisplaySeconds", 0.75f, new ConfigDescription("Currency result display seconds.通貨報酬表示秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 10f), Array.Empty<object>()));
			ReturnToIdleSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Result", "ReturnToIdleSeconds", 0.15f, new ConfigDescription("Outro seconds before returning to idle.アイドル復帰前の終了待機秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 5f), Array.Empty<object>()));
			AccelerateAuthoritativeStateWhenHost = ((BaseUnityPlugin)this).Config.Bind<bool>("HostEffect", "AccelerateAuthoritativeStateWhenHost", true, "When host or singleplayer, shorten authoritative machine state timers.ホストまたはシングル時にガチャ機本体のState待機を短縮");
			MinimumStateSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "MinimumStateSeconds", 0.05f, new ConfigDescription("Minimum seconds kept for important states.重要Stateに残す最小秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>()));
			ResetAnimatorSpeedOnIdle = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "ResetAnimatorSpeedOnIdle", true, "Reset animator speed to 1 when the machine returns to idle.アイドル復帰時にAnimator速度を1へ戻す");
			DoNotSkipRewardSetState = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "DoNotSkipRewardSetState", true, "Do not fully skip states that confirm rewards.報酬確定Stateを完全スキップしない");
			TurboMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Turbo", "TurboMode", true, "Force more aggressive speed values even when old config values remain.既存Config値が残っていてもさらに高速化");
			AllowQueuedMultiUse = ((BaseUnityPlugin)this).Config.Bind<bool>("MultiUse", "AllowQueuedMultiUse", true, "Allow multiple players to queue gacha uses while the machine is busy.ガチャ機が使用中でも複数人の利用要求をキュー化");
			QueueLocalPresses = ((BaseUnityPlugin)this).Config.Bind<bool>("MultiUse", "QueueLocalPresses", true, "Queue local E presses while the machine is busy.ガチャ機が使用中でもローカルのE入力をキュー化");
			QueueRemoteRequests = ((BaseUnityPlugin)this).Config.Bind<bool>("MultiUse", "QueueRemoteRequests", true, "Host queues remote player requests received while the machine is busy.ホストが使用中に受信した参加者の要求をキュー化");
			MaxQueueSize = ((BaseUnityPlugin)this).Config.Bind<int>("MultiUse", "MaxQueueSize", 32, new ConfigDescription("Maximum total queued gacha requests.全体の最大キュー数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 200), Array.Empty<object>()));
			MaxQueuedRequestsPerPlayer = ((BaseUnityPlugin)this).Config.Bind<int>("MultiUse", "MaxQueuedRequestsPerPlayer", 10, new ConfigDescription("Maximum queued gacha requests per player.プレイヤーごとの最大キュー数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			QueueProcessDelaySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("MultiUse", "QueueProcessDelaySeconds", 0.02f, new ConfigDescription("Delay before starting the next queued gacha after Idle.アイドル復帰後に次のキューを開始するまでの秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			QueueInteractDistance = ((BaseUnityPlugin)this).Config.Bind<float>("MultiUse", "QueueInteractDistance", 5f, new ConfigDescription("Maximum distance for local rapid E queue input.ローカルE連打キュー入力を許可する距離", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
			AllowRapidPress = ((BaseUnityPlugin)this).Config.Bind<bool>("RapidInput", "AllowRapidPress", true, "Allow repeated E presses to queue consecutive gacha uses. E連打で連続ガチャをキュー化");
			RapidPressCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("RapidInput", "RapidPressCooldownSeconds", 0.03f, new ConfigDescription("Minimum interval between rapid E queue inputs. E連打キュー入力の最小間隔", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		}

		internal static bool IsEnabled()
		{
			if (Enable != null && Enable.Value && SpeedMode != null)
			{
				return SpeedMode.Value != FastGachaSpeedMode.Vanilla;
			}
			return false;
		}

		internal static bool IsInstant()
		{
			if (!IsEnabled())
			{
				return false;
			}
			if (InstantResult != null)
			{
				if (!InstantResult.Value)
				{
					return SpeedMode.Value == FastGachaSpeedMode.Instant;
				}
				return true;
			}
			return false;
		}

		internal static float GetAnimatorSpeed()
		{
			if (!IsEnabled())
			{
				return 1f;
			}
			float num = ((AnimatorSpeedMultiplier != null) ? AnimatorSpeedMultiplier.Value : 3f);
			if (GetTurboMode())
			{
				num = Mathf.Max(num, 15f);
			}
			return SpeedMode.Value switch
			{
				FastGachaSpeedMode.VeryFast => Mathf.Clamp(Mathf.Max(num, 6f), 1f, 30f), 
				FastGachaSpeedMode.Instant => Mathf.Clamp(Mathf.Max(num, 20f), 1f, 30f), 
				FastGachaSpeedMode.Fast => Mathf.Clamp(num, 1f, 30f), 
				_ => 1f, 
			};
		}

		internal static float GetStateTimerMultiplier()
		{
			if (!IsEnabled())
			{
				return 1f;
			}
			float num = ((StateTimerMultiplier != null) ? StateTimerMultiplier.Value : 0.35f);
			if (GetTurboMode())
			{
				num = Mathf.Min(num, 0.05f);
			}
			return SpeedMode.Value switch
			{
				FastGachaSpeedMode.VeryFast => Mathf.Clamp(Mathf.Min(num, 0.18f), 0.01f, 1f), 
				FastGachaSpeedMode.Instant => Mathf.Clamp(Mathf.Min(num, 0.05f), 0.01f, 1f), 
				FastGachaSpeedMode.Fast => Mathf.Clamp(num, 0.01f, 1f), 
				_ => 1f, 
			};
		}

		internal static float GetMinimumStateSeconds()
		{
			float num = ((MinimumStateSeconds != null) ? MinimumStateSeconds.Value : 0.05f);
			if (GetTurboMode())
			{
				num = Mathf.Min(num, 0.01f);
			}
			return Mathf.Clamp(num, 0.01f, 1f);
		}

		internal static bool ShouldAccelerateAuthoritativeState()
		{
			if (!IsEnabled())
			{
				return false;
			}
			if (AccelerateAuthoritativeStateWhenHost == null || !AccelerateAuthoritativeStateWhenHost.Value)
			{
				return false;
			}
			return GameReflection.IsMasterClientOrSingleplayerSafe();
		}

		internal static float GetCurrencyDisplaySeconds()
		{
			float num = ((CurrencyResultDisplaySeconds != null) ? CurrencyResultDisplaySeconds.Value : 0.75f);
			if (!GetTurboMode())
			{
				return num;
			}
			return Mathf.Min(num, 0.1f);
		}

		internal static float GetCosmeticDisplaySeconds()
		{
			float num = ((CosmeticResultDisplaySeconds != null) ? CosmeticResultDisplaySeconds.Value : 1f);
			if (!GetTurboMode())
			{
				return num;
			}
			return Mathf.Min(num, 0.15f);
		}

		internal static float GetReturnToIdleSeconds()
		{
			float num = ((ReturnToIdleSeconds != null) ? ReturnToIdleSeconds.Value : 0.15f);
			if (!GetTurboMode())
			{
				return num;
			}
			return Mathf.Min(num, 0.03f);
		}

		internal static bool GetSkipTokenOutro()
		{
			if (SkipTokenOutro != null)
			{
				return SkipTokenOutro.Value;
			}
			return false;
		}

		internal static bool GetSkipSpinWait()
		{
			if (SkipSpinWait != null)
			{
				return SkipSpinWait.Value;
			}
			return false;
		}

		internal static bool GetSkipSEWait()
		{
			if (SkipSEWait != null)
			{
				return SkipSEWait.Value;
			}
			return false;
		}

		internal static bool GetSkipConfettiWait()
		{
			if (SkipConfettiWait != null)
			{
				return SkipConfettiWait.Value;
			}
			return false;
		}

		internal static bool GetResetAnimatorSpeedOnIdle()
		{
			if (ResetAnimatorSpeedOnIdle != null)
			{
				return ResetAnimatorSpeedOnIdle.Value;
			}
			return true;
		}

		internal static bool GetDoNotSkipRewardSetState()
		{
			if (DoNotSkipRewardSetState != null)
			{
				return DoNotSkipRewardSetState.Value;
			}
			return true;
		}

		internal static bool GetTurboMode()
		{
			if (TurboMode != null)
			{
				return TurboMode.Value;
			}
			return false;
		}

		internal static bool GetAllowQueuedMultiUse()
		{
			if (AllowQueuedMultiUse != null)
			{
				return AllowQueuedMultiUse.Value;
			}
			return false;
		}

		internal static bool GetQueueLocalPresses()
		{
			if (QueueLocalPresses != null)
			{
				return QueueLocalPresses.Value;
			}
			return false;
		}

		internal static bool GetQueueRemoteRequests()
		{
			if (QueueRemoteRequests != null)
			{
				return QueueRemoteRequests.Value;
			}
			return false;
		}

		internal static int GetMaxQueueSize()
		{
			if (MaxQueueSize == null)
			{
				return 32;
			}
			return Mathf.Clamp(MaxQueueSize.Value, 1, 200);
		}

		internal static int GetMaxQueuedRequestsPerPlayer()
		{
			if (MaxQueuedRequestsPerPlayer == null)
			{
				return 10;
			}
			return Mathf.Clamp(MaxQueuedRequestsPerPlayer.Value, 1, 100);
		}

		internal static float GetQueueProcessDelaySeconds()
		{
			if (QueueProcessDelaySeconds == null)
			{
				return 0.02f;
			}
			return Mathf.Clamp(QueueProcessDelaySeconds.Value, 0f, 1f);
		}

		internal static float GetQueueInteractDistance()
		{
			if (QueueInteractDistance == null)
			{
				return 5f;
			}
			return Mathf.Clamp(QueueInteractDistance.Value, 1f, 20f);
		}

		internal static bool GetAllowRapidPress()
		{
			if (AllowRapidPress != null)
			{
				return AllowRapidPress.Value;
			}
			return false;
		}

		internal static float GetRapidPressCooldownSeconds()
		{
			if (RapidPressCooldownSeconds == null)
			{
				return 0.03f;
			}
			return Mathf.Clamp(RapidPressCooldownSeconds.Value, 0f, 1f);
		}

		internal static void WriteDebugLog(string message)
		{
			if (Log != null && ShowDebugLog != null && ShowDebugLog.Value)
			{
				Log.LogInfo((object)message);
			}
		}

		internal static void WriteFailureLog(string message, Exception ex)
		{
			if (Log != null)
			{
				Log.LogError((object)("Failure: " + message + "\n" + ex));
			}
		}
	}
	public enum FastGachaSpeedMode
	{
		Vanilla,
		Fast,
		VeryFast,
		Instant
	}
	internal static class GameReflection
	{
		private static Type semiFuncType;

		private static Type inputKeyType;

		private static Type rpcTargetType;

		private static Type metaManagerType;

		private static MethodInfo semiFuncIsMasterClientOrSingleplayerMethod;

		private static MethodInfo semiFuncIsMultiplayerMethod;

		private static MethodInfo semiFuncPlayerGetLocalMethod;

		private static MethodInfo semiFuncPlayerGetListMethod;

		private static MethodInfo semiFuncInputDownMethod;

		private static FieldInfo metaManagerInstanceField;

		private static FieldInfo metaManagerCosmeticTokensField;

		private static FieldInfo machineStateCurrentField;

		private static FieldInfo machineStateTimerField;

		private static FieldInfo machineAnimatorField;

		private static FieldInfo machinePhotonViewField;

		private static FieldInfo machineInteractingPlayerField;

		private static MethodInfo machineInteractSetMethod;

		private static FieldInfo machineScreenSpinStoppedField;

		private static FieldInfo machineScreenSpinStartedField;

		private static FieldInfo machineScreenSpinSpeedField;

		private static FieldInfo machineScreenSpinTimeField;

		private static FieldInfo machineScreenSpinSettleLerpField;

		private static FieldInfo machineScreenSpinningFastField;

		private static FieldInfo machineScreenSpinTransformField;

		private static FieldInfo machineScreenSpinSettleTransformField;

		private static FieldInfo animatorUnityAnimatorField;

		private static FieldInfo animatorControllerField;

		private static FieldInfo animatorTokenIntroDoneField;

		private static FieldInfo animatorTokenImpactDoneField;

		private static FieldInfo confettiActiveTimerField;

		private static FieldInfo playerAvatarPhotonViewField;

		private static PropertyInfo photonViewViewIDProperty;

		private static PropertyInfo photonViewOwnerProperty;

		private static MethodInfo photonViewRpcMethod;

		private static PropertyInfo photonMessageInfoSenderProperty;

		internal static void Initialize()
		{
			Type type = AccessTools.TypeByName("CosmeticShopMachine");
			Type type2 = AccessTools.TypeByName("CosmeticShopMachineAnimator");
			Type type3 = AccessTools.TypeByName("CosmeticShopMachineConfetti");
			Type type4 = AccessTools.TypeByName("PlayerAvatar");
			Type type5 = AccessTools.TypeByName("Photon.Pun.PhotonView");
			Type type6 = AccessTools.TypeByName("Photon.Pun.PhotonMessageInfo");
			inputKeyType = AccessTools.TypeByName("InputKey");
			rpcTargetType = AccessTools.TypeByName("Photon.Pun.RpcTarget");
			metaManagerType = AccessTools.TypeByName("MetaManager");
			semiFuncType = AccessTools.TypeByName("SemiFunc");
			if (semiFuncType != null)
			{
				semiFuncIsMasterClientOrSingleplayerMethod = AccessTools.Method(semiFuncType, "IsMasterClientOrSingleplayer", (Type[])null, (Type[])null);
				semiFuncIsMultiplayerMethod = AccessTools.Method(semiFuncType, "IsMultiplayer", (Type[])null, (Type[])null);
				semiFuncPlayerGetLocalMethod = AccessTools.Method(semiFuncType, "PlayerGetLocal", (Type[])null, (Type[])null);
				semiFuncPlayerGetListMethod = AccessTools.Method(semiFuncType, "PlayerGetList", (Type[])null, (Type[])null);
				semiFuncInputDownMethod = AccessTools.Method(semiFuncType, "InputDown", (Type[])null, (Type[])null);
			}
			if (metaManagerType != null)
			{
				metaManagerInstanceField = AccessTools.Field(metaManagerType, "instance");
				metaManagerCosmeticTokensField = AccessTools.Field(metaManagerType, "cosmeticTokens");
			}
			if (type5 != null)
			{
				photonViewViewIDProperty = AccessTools.Property(type5, "ViewID");
				photonViewOwnerProperty = AccessTools.Property(type5, "Owner");
				if (rpcTargetType != null)
				{
					photonViewRpcMethod = AccessTools.Method(type5, "RPC", new Type[3]
					{
						typeof(string),
						rpcTargetType,
						typeof(object[])
					}, (Type[])null);
				}
			}
			if (type6 != null)
			{
				photonMessageInfoSenderProperty = AccessTools.Property(type6, "Sender");
			}
			if (type4 != null)
			{
				playerAvatarPhotonViewField = AccessTools.Field(type4, "photonView");
			}
			if (type != null)
			{
				machineStateCurrentField = AccessTools.Field(type, "stateCurrent");
				machineStateTimerField = AccessTools.Field(type, "stateTimer");
				machineAnimatorField = AccessTools.Field(type, "animator");
				machinePhotonViewField = AccessTools.Field(type, "photonView");
				machineInteractingPlayerField = AccessTools.Field(type, "interactingPlayer");
				machineInteractSetMethod = AccessTools.Method(type, "InteractSet", (Type[])null, (Type[])null);
				machineScreenSpinStoppedField = AccessTools.Field(type, "screenSpinStopped");
				machineScreenSpinStartedField = AccessTools.Field(type, "screenSpinStarted");
				machineScreenSpinSpeedField = AccessTools.Field(type, "screenSpinSpeed");
				machineScreenSpinTimeField = AccessTools.Field(type, "screenSpinTime");
				machineScreenSpinSettleLerpField = AccessTools.Field(type, "screenSpinSettleLerp");
				machineScreenSpinningFastField = AccessTools.Field(type, "screenSpinningFast");
				machineScreenSpinTransformField = AccessTools.Field(type, "screenSpinTransform");
				machineScreenSpinSettleTransformField = AccessTools.Field(type, "screenSpinSettleTransform");
			}
			if (type2 != null)
			{
				animatorUnityAnimatorField = AccessTools.Field(type2, "animator");
				animatorControllerField = AccessTools.Field(type2, "controller");
				animatorTokenIntroDoneField = AccessTools.Field(type2, "tokenIntroDone");
				animatorTokenImpactDoneField = AccessTools.Field(type2, "tokenImpactDone");
			}
			if (type3 != null)
			{
				confettiActiveTimerField = AccessTools.Field(type3, "activeTimer");
			}
		}

		internal static bool IsMasterClientOrSingleplayerSafe()
		{
			try
			{
				if (semiFuncIsMasterClientOrSingleplayerMethod == null)
				{
					return false;
				}
				object obj = semiFuncIsMasterClientOrSingleplayerMethod.Invoke(null, null);
				return obj is bool && (bool)obj;
			}
			catch
			{
				return false;
			}
		}

		internal static bool IsMultiplayerSafe()
		{
			try
			{
				if (semiFuncIsMultiplayerMethod == null)
				{
					return false;
				}
				object obj = semiFuncIsMultiplayerMethod.Invoke(null, null);
				return obj is bool && (bool)obj;
			}
			catch
			{
				return false;
			}
		}

		internal static bool IsInteractInputDownSafe()
		{
			try
			{
				if (semiFuncInputDownMethod == null || inputKeyType == null)
				{
					return false;
				}
				object obj = Enum.Parse(inputKeyType, "Interact");
				object obj2 = semiFuncInputDownMethod.Invoke(null, new object[1] { obj });
				return obj2 is bool && (bool)obj2;
			}
			catch
			{
				return false;
			}
		}

		internal static object GetLocalPlayer()
		{
			try
			{
				if (semiFuncPlayerGetLocalMethod == null)
				{
					return null;
				}
				return semiFuncPlayerGetLocalMethod.Invoke(null, null);
			}
			catch
			{
				return null;
			}
		}

		internal static IEnumerable GetPlayerList()
		{
			try
			{
				if (semiFuncPlayerGetListMethod == null)
				{
					return null;
				}
				return semiFuncPlayerGetListMethod.Invoke(null, null) as IEnumerable;
			}
			catch
			{
				return null;
			}
		}

		internal static string GetStateName(object state)
		{
			if (state == null)
			{
				return string.Empty;
			}
			return state.ToString();
		}

		internal static string GetCurrentStateName(object machine)
		{
			try
			{
				if (machine == null || machineStateCurrentField == null)
				{
					return "Idle";
				}
				return GetStateName(machineStateCurrentField.GetValue(machine));
			}
			catch
			{
				return "Idle";
			}
		}

		internal static object GetAnimatorController(object animator)
		{
			try
			{
				if (animator == null || animatorControllerField == null)
				{
					return null;
				}
				return animatorControllerField.GetValue(animator);
			}
			catch
			{
				return null;
			}
		}

		internal static object GetMachineAnimator(object machine)
		{
			try
			{
				if (machine == null || machineAnimatorField == null)
				{
					return null;
				}
				return machineAnimatorField.GetValue(machine);
			}
			catch
			{
				return null;
			}
		}

		internal static float GetStateTimer(object machine)
		{
			try
			{
				if (machine == null || machineStateTimerField == null)
				{
					return 0f;
				}
				object value = machineStateTimerField.GetValue(machine);
				return (value is float) ? ((float)value) : 0f;
			}
			catch
			{
				return 0f;
			}
		}

		internal static object GetInteractingPlayer(object machine)
		{
			try
			{
				if (machine == null || machineInteractingPlayerField == null)
				{
					return null;
				}
				return machineInteractingPlayerField.GetValue(machine);
			}
			catch
			{
				return null;
			}
		}

		internal static bool IsSamePlayer(object left, object right)
		{
			if (left == null || right == null)
			{
				return false;
			}
			return GetPlayerViewId(left) == GetPlayerViewId(right);
		}

		internal static int GetPlayerViewId(object player)
		{
			try
			{
				object playerPhotonView = GetPlayerPhotonView(player);
				if (playerPhotonView == null || photonViewViewIDProperty == null)
				{
					return -1;
				}
				object value = photonViewViewIDProperty.GetValue(playerPhotonView, null);
				return (value is int) ? ((int)value) : (-1);
			}
			catch
			{
				return -1;
			}
		}

		internal static object GetPlayerPhotonView(object player)
		{
			try
			{
				if (player == null || playerAvatarPhotonViewField == null)
				{
					return null;
				}
				return playerAvatarPhotonViewField.GetValue(player);
			}
			catch
			{
				return null;
			}
		}

		internal static object GetMachinePhotonView(object machine)
		{
			try
			{
				if (machine == null || machinePhotonViewField == null)
				{
					return null;
				}
				return machinePhotonViewField.GetValue(machine);
			}
			catch
			{
				return null;
			}
		}

		internal static object GetPhotonMessageSender(object photonMessageInfo)
		{
			try
			{
				if (photonMessageInfo == null || photonMessageInfoSenderProperty == null)
				{
					return null;
				}
				return photonMessageInfoSenderProperty.GetValue(photonMessageInfo, null);
			}
			catch
			{
				return null;
			}
		}

		internal static object FindPlayerBySenderInfo(object photonMessageInfo)
		{
			try
			{
				object photonMessageSender = GetPhotonMessageSender(photonMessageInfo);
				if (photonMessageSender == null)
				{
					return null;
				}
				IEnumerable playerList = GetPlayerList();
				if (playerList == null)
				{
					return null;
				}
				foreach (object item in playerList)
				{
					object playerPhotonView = GetPlayerPhotonView(item);
					if (playerPhotonView != null && !(photonViewOwnerProperty == null))
					{
						object value = photonViewOwnerProperty.GetValue(playerPhotonView, null);
						if (object.Equals(value, photonMessageSender))
						{
							return item;
						}
					}
				}
				return null;
			}
			catch
			{
				return null;
			}
		}

		internal static int GetLocalTokenCount()
		{
			try
			{
				return GetCosmeticTokens()?.Count ?? 0;
			}
			catch
			{
				return 0;
			}
		}

		internal static int GetLocalTokenRarityAtOffset(int pendingOffset)
		{
			try
			{
				IList cosmeticTokens = GetCosmeticTokens();
				if (cosmeticTokens == null || cosmeticTokens.Count == 0)
				{
					return -1;
				}
				int num = cosmeticTokens.Count - 1 - Mathf.Max(0, pendingOffset);
				if (num < 0 || num >= cosmeticTokens.Count)
				{
					return -1;
				}
				object obj = cosmeticTokens[num];
				return (obj is int) ? ((int)obj) : (-1);
			}
			catch
			{
				return -1;
			}
		}

		private static IList GetCosmeticTokens()
		{
			try
			{
				if (metaManagerInstanceField == null || metaManagerCosmeticTokensField == null)
				{
					return null;
				}
				object value = metaManagerInstanceField.GetValue(null);
				if (value == null)
				{
					return null;
				}
				return metaManagerCosmeticTokensField.GetValue(value) as IList;
			}
			catch
			{
				return null;
			}
		}

		internal static bool SendInteractRpcToMaster(object machine, int rarity)
		{
			try
			{
				object machinePhotonView = GetMachinePhotonView(machine);
				if (machinePhotonView == null || photonViewRpcMethod == null || rpcTargetType == null)
				{
					return false;
				}
				object obj = Enum.Parse(rpcTargetType, "MasterClient");
				photonViewRpcMethod.Invoke(machinePhotonView, new object[3]
				{
					"InteractClientRPC",
					obj,
					new object[1] { rarity }
				});
				return true;
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("SendInteractRpcToMaster", ex);
				return false;
			}
		}

		internal static bool InvokeInteractSet(object machine, object player, int rarity)
		{
			try
			{
				if (machine == null || player == null || machineInteractSetMethod == null)
				{
					return false;
				}
				machineInteractSetMethod.Invoke(machine, new object[2] { player, rarity });
				return true;
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("InvokeInteractSet", ex);
				return false;
			}
		}

		internal static bool IsLocalPlayerNearMachine(object machine)
		{
			//IL_0031: 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)
			try
			{
				object localPlayer = GetLocalPlayer();
				Component val = (Component)((localPlayer is Component) ? localPlayer : null);
				Component val2 = (Component)((machine is Component) ? machine : null);
				if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
				{
					return false;
				}
				float num = Vector3.Distance(val.transform.position, val2.transform.position);
				return num <= FastCosmeticGachaPlugin.GetQueueInteractDistance();
			}
			catch
			{
				return false;
			}
		}

		internal static void SetStateTimer(object machine, float value)
		{
			try
			{
				if (machine != null && !(machineStateTimerField == null))
				{
					machineStateTimerField.SetValue(machine, value);
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("SetStateTimer", ex);
			}
		}

		internal static void SetTokenIntroDone(object animator, bool value)
		{
			try
			{
				if (animator != null && !(animatorTokenIntroDoneField == null))
				{
					animatorTokenIntroDoneField.SetValue(animator, value);
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("SetTokenIntroDone", ex);
			}
		}

		internal static void SetTokenImpactDone(object animator, bool value)
		{
			try
			{
				if (animator != null && !(animatorTokenImpactDoneField == null))
				{
					animatorTokenImpactDoneField.SetValue(animator, value);
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("SetTokenImpactDone", ex);
			}
		}

		internal static Animator GetUnityAnimator(object animator)
		{
			try
			{
				if (animator == null || animatorUnityAnimatorField == null)
				{
					return null;
				}
				object? value = animatorUnityAnimatorField.GetValue(animator);
				return (Animator)((value is Animator) ? value : null);
			}
			catch
			{
				return null;
			}
		}

		internal static void SetConfettiActiveTimer(object confetti, float value)
		{
			try
			{
				if (confetti != null && !(confettiActiveTimerField == null))
				{
					confettiActiveTimerField.SetValue(confetti, value);
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("SetConfettiActiveTimer", ex);
			}
		}

		internal static void ForceScreenStop(object machine)
		{
			//IL_0095: 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)
			try
			{
				if (machine != null)
				{
					SetFieldValue(machineScreenSpinStoppedField, machine, true);
					SetFieldValue(machineScreenSpinStartedField, machine, false);
					SetFieldValue(machineScreenSpinningFastField, machine, false);
					SetFieldValue(machineScreenSpinSpeedField, machine, 0f);
					SetFieldValue(machineScreenSpinTimeField, machine, 0f);
					SetFieldValue(machineScreenSpinSettleLerpField, machine, 1f);
					object fieldValue = GetFieldValue(machineScreenSpinTransformField, machine);
					Transform val = (Transform)((fieldValue is Transform) ? fieldValue : null);
					if ((Object)(object)val != (Object)null)
					{
						val.localRotation = Quaternion.identity;
					}
					object fieldValue2 = GetFieldValue(machineScreenSpinSettleTransformField, machine);
					Transform val2 = (Transform)((fieldValue2 is Transform) ? fieldValue2 : null);
					if ((Object)(object)val2 != (Object)null)
					{
						val2.localEulerAngles = new Vector3(0f, 20f, 0f);
					}
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("ForceScreenStop", ex);
			}
		}

		private static void SetFieldValue(FieldInfo field, object instance, object value)
		{
			if (field != null && instance != null)
			{
				field.SetValue(instance, value);
			}
		}

		private static object GetFieldValue(FieldInfo field, object instance)
		{
			if (field == null || instance == null)
			{
				return null;
			}
			return field.GetValue(instance);
		}
	}
	internal static class StateUtility
	{
		internal static bool IsGachaActiveState(string stateName)
		{
			if (!string.IsNullOrEmpty(stateName))
			{
				return stateName != "Idle";
			}
			return false;
		}

		internal static bool IsRewardSetState(string stateName)
		{
			if (!(stateName == "RewardCosmeticIntro"))
			{
				return stateName == "RewardCurrency";
			}
			return true;
		}

		internal static bool CanSkipAnimatorWait(string stateName)
		{
			switch (stateName)
			{
			default:
				return stateName == "RewardCosmeticFrameOutro";
			case "FetchRewardDone":
			case "TokenOutro":
			case "RewardCurrencyIntro":
			case "RewardCosmeticIntro":
			case "RewardCosmeticConfetti":
			case "RewardCosmeticFrame":
				return true;
			}
		}

		internal static float GetShortenedTimer(string stateName, float originalSeconds)
		{
			float num = FastCosmeticGachaPlugin.GetMinimumStateSeconds();
			float stateTimerMultiplier = FastCosmeticGachaPlugin.GetStateTimerMultiplier();
			bool flag = FastCosmeticGachaPlugin.IsInstant();
			if (!FastCosmeticGachaPlugin.IsEnabled())
			{
				return originalSeconds;
			}
			if (stateName == "FetchReward")
			{
				return originalSeconds;
			}
			if (FastCosmeticGachaPlugin.GetDoNotSkipRewardSetState() && IsRewardSetState(stateName))
			{
				num = Mathf.Max(num, 0.05f);
			}
			switch (stateName)
			{
			case "Interact":
				return Mathf.Max(num, originalSeconds * stateTimerMultiplier);
			case "FetchRewardDone":
				if (flag || FastCosmeticGachaPlugin.GetSkipSEWait() || FastCosmeticGachaPlugin.GetSkipSpinWait())
				{
					return num;
				}
				return Mathf.Max(num, originalSeconds * stateTimerMultiplier);
			case "TokenOutro":
				if (flag || FastCosmeticGachaPlugin.GetSkipTokenOutro())
				{
					return num;
				}
				return Mathf.Max(num, originalSeconds * stateTimerMultiplier);
			case "RewardCurrencyIntro":
				if (flag)
				{
					return num;
				}
				return Mathf.Max(num, originalSeconds * stateTimerMultiplier);
			case "RewardCurrency":
				if (flag)
				{
					return num;
				}
				return Mathf.Max(num, FastCosmeticGachaPlugin.GetCurrencyDisplaySeconds());
			case "RewardCurrencyOutro":
				return Mathf.Max(num, FastCosmeticGachaPlugin.GetReturnToIdleSeconds());
			case "RewardCosmeticIntro":
				if (flag)
				{
					return num;
				}
				return Mathf.Max(num, originalSeconds * stateTimerMultiplier);
			case "RewardCosmeticConfetti":
				if (flag || FastCosmeticGachaPlugin.GetSkipConfettiWait())
				{
					return num;
				}
				return Mathf.Max(num, originalSeconds * stateTimerMultiplier);
			case "RewardCosmeticFrame":
				if (flag)
				{
					return num;
				}
				return Mathf.Max(num, FastCosmeticGachaPlugin.GetCosmeticDisplaySeconds());
			case "RewardCosmeticFrameOutro":
				if (flag)
				{
					return num;
				}
				return Mathf.Max(num, originalSeconds * stateTimerMultiplier);
			case "RewardCosmeticOutro":
				return Mathf.Max(num, FastCosmeticGachaPlugin.GetReturnToIdleSeconds());
			default:
				return Mathf.Max(num, originalSeconds * stateTimerMultiplier);
			}
		}

		internal static float GetKnownOriginalTimer(string stateName)
		{
			return stateName switch
			{
				"Interact" => 0.1f, 
				"FetchRewardDone" => 0.1f, 
				"TokenOutro" => 1f, 
				"RewardCurrencyIntro" => 1f, 
				"RewardCurrency" => 1f, 
				"RewardCurrencyOutro" => 0.5f, 
				"RewardCosmeticIntro" => 1.5f, 
				"RewardCosmeticConfetti" => 1.5f, 
				"RewardCosmeticFrame" => 2f, 
				"RewardCosmeticFrameOutro" => 1f, 
				"RewardCosmeticOutro" => 0.5f, 
				_ => 0f, 
			};
		}
	}
	internal sealed class QueuedGachaRequest
	{
		internal object Player;

		internal int PlayerViewId;

		internal int Rarity;

		internal bool LocalRequest;

		internal float CreatedTime;

		internal string Source;
	}
	internal static class QueuedGachaManager
	{
		private static readonly List<QueuedGachaRequest> PendingRequests = new List<QueuedGachaRequest>();

		private static int localPendingRequests;

		private static bool localQueuedRequestActive;

		private static float lastLocalPressTime = -999f;

		private static float nextProcessTime;

		internal static void CaptureLocalPress(object machine, string stateBeforeUpdate)
		{
			try
			{
				if (!FastCosmeticGachaPlugin.IsEnabled() || !FastCosmeticGachaPlugin.GetAllowQueuedMultiUse() || !FastCosmeticGachaPlugin.GetAllowRapidPress() || !FastCosmeticGachaPlugin.GetQueueLocalPresses() || machine == null || stateBeforeUpdate == "Idle" || Time.time - lastLocalPressTime < FastCosmeticGachaPlugin.GetRapidPressCooldownSeconds() || !GameReflection.IsInteractInputDownSafe() || !GameReflection.IsLocalPlayerNearMachine(machine))
				{
					return;
				}
				int localTokenCount = GameReflection.GetLocalTokenCount();
				int localActiveUnconsumedOffset = GetLocalActiveUnconsumedOffset(machine, stateBeforeUpdate);
				int num = localActiveUnconsumedOffset + localPendingRequests;
				if (localTokenCount <= 0 || num >= localTokenCount)
				{
					return;
				}
				int localTokenRarityAtOffset = GameReflection.GetLocalTokenRarityAtOffset(num);
				if (!IsValidRarity(localTokenRarityAtOffset))
				{
					return;
				}
				object localPlayer = GameReflection.GetLocalPlayer();
				if (localPlayer == null)
				{
					return;
				}
				if (GameReflection.IsMasterClientOrSingleplayerSafe())
				{
					if (Enqueue(machine, localPlayer, localTokenRarityAtOffset, localRequest: true, "LocalHost"))
					{
						lastLocalPressTime = Time.time;
					}
				}
				else if (GameReflection.SendInteractRpcToMaster(machine, localTokenRarityAtOffset))
				{
					localPendingRequests++;
					lastLocalPressTime = Time.time;
					FastCosmeticGachaPlugin.WriteDebugLog("Rapid request sent to host. PendingLocal=" + localPendingRequests);
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("CaptureLocalPress", ex);
			}
		}

		internal static bool TryQueueRemoteRequest(object machine, object[] args)
		{
			try
			{
				if (!FastCosmeticGachaPlugin.IsEnabled() || !FastCosmeticGachaPlugin.GetAllowQueuedMultiUse() || !FastCosmeticGachaPlugin.GetQueueRemoteRequests())
				{
					return false;
				}
				if (!GameReflection.IsMasterClientOrSingleplayerSafe())
				{
					return false;
				}
				if (machine == null || args == null || args.Length < 2)
				{
					return false;
				}
				string currentStateName = GameReflection.GetCurrentStateName(machine);
				if (currentStateName == "Idle")
				{
					return false;
				}
				int rarity = ((args[0] is int) ? ((int)args[0]) : (-1));
				if (!IsValidRarity(rarity))
				{
					return true;
				}
				object obj = GameReflection.FindPlayerBySenderInfo(args[1]);
				if (obj == null)
				{
					return true;
				}
				Enqueue(machine, obj, rarity, localRequest: false, "RemoteRPC");
				return true;
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("TryQueueRemoteRequest", ex);
				return false;
			}
		}

		internal static void ProcessQueue(object machine)
		{
			try
			{
				if (!FastCosmeticGachaPlugin.IsEnabled() || !FastCosmeticGachaPlugin.GetAllowQueuedMultiUse())
				{
					PendingRequests.Clear();
				}
				else
				{
					if (!GameReflection.IsMasterClientOrSingleplayerSafe() || machine == null || PendingRequests.Count == 0 || Time.time < nextProcessTime)
					{
						return;
					}
					string currentStateName = GameReflection.GetCurrentStateName(machine);
					if (currentStateName != "Idle")
					{
						return;
					}
					while (PendingRequests.Count > 0)
					{
						QueuedGachaRequest queuedGachaRequest = PendingRequests[0];
						PendingRequests.RemoveAt(0);
						if (queuedGachaRequest != null && queuedGachaRequest.Player != null && IsValidRarity(queuedGachaRequest.Rarity) && GameReflection.InvokeInteractSet(machine, queuedGachaRequest.Player, queuedGachaRequest.Rarity))
						{
							nextProcessTime = Time.time + FastCosmeticGachaPlugin.GetQueueProcessDelaySeconds();
							FastCosmeticGachaPlugin.WriteDebugLog("Queued gacha started. PlayerViewID=" + queuedGachaRequest.PlayerViewId + " Rarity=" + queuedGachaRequest.Rarity + " Remaining=" + PendingRequests.Count);
							break;
						}
					}
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("ProcessQueue", ex);
			}
		}

		internal static void MarkLocalQueuedRequestStarted(object machine)
		{
			try
			{
				if (localPendingRequests > 0)
				{
					object interactingPlayer = GameReflection.GetInteractingPlayer(machine);
					object localPlayer = GameReflection.GetLocalPlayer();
					if (GameReflection.IsSamePlayer(interactingPlayer, localPlayer))
					{
						localQueuedRequestActive = true;
						FastCosmeticGachaPlugin.WriteDebugLog("Local queued request started.");
					}
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("MarkLocalQueuedRequestStarted", ex);
			}
		}

		internal static void RewardSetPostfix(object machine)
		{
			try
			{
				object interactingPlayer = GameReflection.GetInteractingPlayer(machine);
				object localPlayer = GameReflection.GetLocalPlayer();
				if (GameReflection.IsSamePlayer(interactingPlayer, localPlayer) && localQueuedRequestActive && localPendingRequests > 0)
				{
					localPendingRequests--;
					localQueuedRequestActive = false;
					FastCosmeticGachaPlugin.WriteDebugLog("Local queued pending consumed. PendingLocal=" + localPendingRequests);
				}
				if (GameReflection.GetLocalTokenCount() == 0)
				{
					localPendingRequests = 0;
					localQueuedRequestActive = false;
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("RewardSetPostfix", ex);
			}
		}

		private static bool Enqueue(object machine, object player, int rarity, bool localRequest, string source)
		{
			if (machine == null || player == null || !IsValidRarity(rarity))
			{
				return false;
			}
			if (PendingRequests.Count >= FastCosmeticGachaPlugin.GetMaxQueueSize())
			{
				return false;
			}
			int playerViewId = GameReflection.GetPlayerViewId(player);
			int num = 0;
			for (int i = 0; i < PendingRequests.Count; i++)
			{
				if (PendingRequests[i] != null && PendingRequests[i].PlayerViewId == playerViewId)
				{
					num++;
				}
			}
			if (num >= FastCosmeticGachaPlugin.GetMaxQueuedRequestsPerPlayer())
			{
				return false;
			}
			if (localRequest)
			{
				int localTokenCount = GameReflection.GetLocalTokenCount();
				if (localTokenCount <= 0 || localPendingRequests >= localTokenCount)
				{
					return false;
				}
				localPendingRequests++;
			}
			PendingRequests.Add(new QueuedGachaRequest
			{
				Player = player,
				PlayerViewId = playerViewId,
				Rarity = rarity,
				LocalRequest = localRequest,
				CreatedTime = Time.time,
				Source = source
			});
			FastCosmeticGachaPlugin.WriteDebugLog("Queued gacha request. Source=" + source + " PlayerViewID=" + playerViewId + " Rarity=" + rarity + " Queue=" + PendingRequests.Count);
			return true;
		}

		private static int GetLocalActiveUnconsumedOffset(object machine, string stateName)
		{
			if (machine == null || string.IsNullOrEmpty(stateName))
			{
				return 0;
			}
			if (stateName != "Interact" && stateName != "FetchReward" && stateName != "FetchRewardDone" && stateName != "TokenOutro" && stateName != "RewardCurrencyIntro")
			{
				return 0;
			}
			object interactingPlayer = GameReflection.GetInteractingPlayer(machine);
			object localPlayer = GameReflection.GetLocalPlayer();
			return GameReflection.IsSamePlayer(interactingPlayer, localPlayer) ? 1 : 0;
		}

		private static bool IsValidRarity(int rarity)
		{
			if (rarity >= 0)
			{
				return rarity <= 3;
			}
			return false;
		}
	}
	internal static class MachineUpdateHook
	{
		private static void Prefix(object __instance, out string __state)
		{
			__state = GameReflection.GetCurrentStateName(__instance);
		}

		private static void Postfix(object __instance, string __state)
		{
			try
			{
				if (__instance != null)
				{
					QueuedGachaManager.CaptureLocalPress(__instance, __state);
					QueuedGachaManager.ProcessQueue(__instance);
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("Machine.Update Postfix", ex);
			}
		}
	}
	internal static class InteractClientRpcHook
	{
		private static bool Prefix(object __instance, object[] __args)
		{
			try
			{
				if (QueuedGachaManager.TryQueueRemoteRequest(__instance, __args))
				{
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("InteractClientRPC Prefix", ex);
				return true;
			}
		}
	}
	internal static class RewardSetHook
	{
		private static void Postfix(object __instance)
		{
			QueuedGachaManager.RewardSetPostfix(__instance);
		}
	}
	internal static class StateRpcHook
	{
		private static void Postfix(object __instance, object[] __args)
		{
			try
			{
				if (__instance == null || !FastCosmeticGachaPlugin.IsEnabled())
				{
					return;
				}
				string text = string.Empty;
				if (__args != null && __args.Length != 0)
				{
					text = GameReflection.GetStateName(__args[0]);
				}
				if (string.IsNullOrEmpty(text))
				{
					text = GameReflection.GetCurrentStateName(__instance);
				}
				if (text == "Interact")
				{
					QueuedGachaManager.MarkLocalQueuedRequestStarted(__instance);
				}
				TryCompleteAnimationWaits(__instance, text);
				if (FastCosmeticGachaPlugin.ShouldAccelerateAuthoritativeState())
				{
					float knownOriginalTimer = StateUtility.GetKnownOriginalTimer(text);
					if (!(knownOriginalTimer <= 0f))
					{
						float shortenedTimer = StateUtility.GetShortenedTimer(text, knownOriginalTimer);
						GameReflection.SetStateTimer(__instance, shortenedTimer);
						FastCosmeticGachaPlugin.WriteDebugLog("State shortened: " + text + " " + knownOriginalTimer.ToString("0.00") + " -> " + shortenedTimer.ToString("0.00"));
					}
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("UpdateStateRPC Postfix", ex);
			}
		}

		private static void TryCompleteAnimationWaits(object machine, string stateName)
		{
			if (machine == null)
			{
				return;
			}
			object machineAnimator = GameReflection.GetMachineAnimator(machine);
			if (machineAnimator != null)
			{
				bool flag = FastCosmeticGachaPlugin.IsInstant();
				if (stateName == "FetchRewardDone" && (flag || FastCosmeticGachaPlugin.GetSkipSEWait() || FastCosmeticGachaPlugin.GetSkipSpinWait()))
				{
					GameReflection.SetTokenIntroDone(machineAnimator, value: true);
				}
				if (StateUtility.CanSkipAnimatorWait(stateName) && (flag || FastCosmeticGachaPlugin.GetSkipSpinWait()))
				{
					GameReflection.SetTokenImpactDone(machineAnimator, value: true);
					GameReflection.ForceScreenStop(machine);
				}
			}
		}
	}
	internal static class AnimatorUpdateHook
	{
		private static void Postfix(object __instance)
		{
			try
			{
				if (__instance == null)
				{
					return;
				}
				Animator unityAnimator = GameReflection.GetUnityAnimator(__instance);
				if ((Object)(object)unityAnimator == (Object)null)
				{
					return;
				}
				object animatorController = GameReflection.GetAnimatorController(__instance);
				string currentStateName = GameReflection.GetCurrentStateName(animatorController);
				if (!FastCosmeticGachaPlugin.IsEnabled() || !StateUtility.IsGachaActiveState(currentStateName))
				{
					if (FastCosmeticGachaPlugin.GetResetAnimatorSpeedOnIdle())
					{
						unityAnimator.speed = 1f;
					}
					return;
				}
				unityAnimator.speed = FastCosmeticGachaPlugin.GetAnimatorSpeed();
				bool flag = FastCosmeticGachaPlugin.IsInstant();
				if (currentStateName == "FetchRewardDone" && (flag || FastCosmeticGachaPlugin.GetSkipSEWait() || FastCosmeticGachaPlugin.GetSkipSpinWait()))
				{
					GameReflection.SetTokenIntroDone(__instance, value: true);
				}
				if (StateUtility.CanSkipAnimatorWait(currentStateName) && (flag || FastCosmeticGachaPlugin.GetSkipSpinWait()))
				{
					GameReflection.SetTokenImpactDone(__instance, value: true);
					GameReflection.ForceScreenStop(animatorController);
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("Animator.Update Postfix", ex);
			}
		}
	}
	internal static class ScreenSpinHook
	{
		private static void Postfix(object __instance)
		{
			try
			{
				if (__instance == null || !FastCosmeticGachaPlugin.IsEnabled())
				{
					return;
				}
				string currentStateName = GameReflection.GetCurrentStateName(__instance);
				if (StateUtility.CanSkipAnimatorWait(currentStateName) && (FastCosmeticGachaPlugin.IsInstant() || FastCosmeticGachaPlugin.GetSkipSpinWait()))
				{
					object machineAnimator = GameReflection.GetMachineAnimator(__instance);
					if (machineAnimator != null)
					{
						GameReflection.SetTokenImpactDone(machineAnimator, value: true);
					}
					GameReflection.ForceScreenStop(__instance);
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("ScreenSpinLogic Postfix", ex);
			}
		}
	}
	internal static class ConfettiSetHook
	{
		private static void Postfix(object __instance)
		{
			try
			{
				if (__instance != null && FastCosmeticGachaPlugin.IsEnabled())
				{
					float minimumStateSeconds = FastCosmeticGachaPlugin.GetMinimumStateSeconds();
					float value = ((!FastCosmeticGachaPlugin.IsInstant() && !FastCosmeticGachaPlugin.GetSkipConfettiWait()) ? Mathf.Max(minimumStateSeconds, 3f * FastCosmeticGachaPlugin.GetStateTimerMultiplier()) : minimumStateSeconds);
					GameReflection.SetConfettiActiveTimer(__instance, value);
					FastCosmeticGachaPlugin.WriteDebugLog("Confetti shortened: 3.00 -> " + value.ToString("0.00"));
				}
			}
			catch (Exception ex)
			{
				FastCosmeticGachaPlugin.WriteFailureLog("Confetti.Set Postfix", ex);
			}
		}
	}
}