plugins/VFiX/VFiX.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HG;
using HG.Coroutines;
using HG.Reflection;
using Microsoft.CodeAnalysis;
using On.RoR2;
using R2API.Utils;
using RoR2;
using RoR2.ContentManagement;
using RoR2.DispatachableEffects;
using RoR2.Orbs;
using RoR2BepInExPack.GameAssetPathsBetter;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;
using VFiX.Cache;
using VFiX.Cache.Serialization;
using VFiX.GrandparentPreSpawnEffect;
using VFiX.PooledEffectCleanup;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("VFiX")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d82053936a7c825be47d8b82d76fee11eb9df854")]
[assembly: AssemblyProduct("VFiX")]
[assembly: AssemblyTitle("VFiX")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 VFiX
{
	public static class AddressableExtensions
	{
		public static void CallOnSuccess<T>(this AsyncOperationHandle<T> handle, Action<T> onSuccess)
		{
			handle.Completed += delegate(AsyncOperationHandle<T> val)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				if ((int)val.Status != 1)
				{
					Log.Error("Failed to load asset " + val.LocationName, "D:\\Git\\RoR2\\VFiX\\VFiX\\AddressableExtensions.cs", "CallOnSuccess", 24);
				}
				else
				{
					onSuccess(val.Result);
				}
			};
		}
	}
	public static class AssetLoadUtils
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static AsyncOperationHandle<T> LoadTempAssetAsync<T>(string assetKey) where T : Object
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return LoadTempAssetAsync<T>(new AssetReferenceT<T>(assetKey));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static AsyncOperationHandle<T> LoadTempAssetAsync<T>(AssetReferenceT<T> assetReference) where T : Object
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return AssetAsyncReferenceManager<T>.LoadAsset(assetReference, (AsyncReferenceHandleUnloadType)0);
		}
	}
	internal sealed class CoroutineResult<T>
	{
		public sealed class CoroutineResultPool : BasePool<CoroutineResult<T>>
		{
			public override void ResetItem(CoroutineResult<T> item)
			{
				item.Value = default(T);
			}

			public CoroutineResultPool()
			{
				((BasePool<CoroutineResult<CoroutineResult<T>>>)(object)this)..ctor();
			}
		}

		public static readonly CoroutineResultPool pool = new CoroutineResultPool();

		public T Value;
	}
	internal static class Log
	{
		private static readonly StringBuilder _sharedStringBuilder;

		private static readonly int _cachedCallerPathPrefixLength;

		private static ManualLogSource _logSource;

		static Log()
		{
			_sharedStringBuilder = new StringBuilder(256);
			_cachedCallerPathPrefixLength = getCallerPathPrefixLength("D:\\Git\\RoR2\\VFiX\\VFiX\\Log.cs");
			static int getCallerPathPrefixLength([CallerFilePath] string callerPath = null)
			{
				int num = callerPath.LastIndexOf("VFiX\\");
				if (num >= 0)
				{
					return num + "VFiX\\".Length;
				}
				Debug.LogError((object)"[VFiX] Logger failed to determine caller path prefix length");
				return 0;
			}
		}

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		private static StringBuilder AppendCallerPrefix(this StringBuilder stringBuilder, string callerPath, string callerMemberName, int callerLineNumber)
		{
			return stringBuilder.Append(callerPath, _cachedCallerPathPrefixLength, callerPath.Length - _cachedCallerPathPrefixLength).Append(':').Append(callerLineNumber)
				.Append(" (")
				.Append(callerMemberName)
				.Append("):");
		}

		private static StringBuilder buildCallerLogString(string callerPath, string callerMemberName, int callerLineNumber, object data)
		{
			return _sharedStringBuilder.Clear().AppendCallerPrefix(callerPath, callerMemberName, callerLineNumber).Append(' ')
				.Append(data);
		}

		[Conditional("DEBUG")]
		internal static void Debug(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogDebug((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[Conditional("DEBUG")]
		internal static void Debug_NoCallerPrefix(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogError((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Error_NoCallerPrefix(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogFatal((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Fatal_NoCallerPrefix(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogInfo((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Info_NoCallerPrefix(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogMessage((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Message_NoCallerPrefix(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogWarning((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Warning_NoCallerPrefix(object data)
		{
			_logSource.LogWarning(data);
		}

		internal static void LogType(LogLevel level, object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			LogType_NoCallerPrefix(level, buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		internal static void LogType_NoCallerPrefix(LogLevel level, object data)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if ((level & 1) != 0)
			{
				Fatal_NoCallerPrefix(data);
			}
			else if ((level & 2) != 0)
			{
				Error_NoCallerPrefix(data);
			}
			else if ((level & 4) != 0)
			{
				Warning_NoCallerPrefix(data);
			}
			else if ((level & 8) != 0)
			{
				Message_NoCallerPrefix(data);
			}
			else if ((level & 0x10) != 0)
			{
				Info_NoCallerPrefix(data);
			}
			else
			{
				_ = level & 0x20;
			}
		}
	}
	[BepInPlugin("Gorakh.VFiX", "VFiX", "1.1.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class VFiXPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "Gorakh.VFiX";

		public const string PluginAuthor = "Gorakh";

		public const string PluginName = "VFiX";

		public const string PluginVersion = "1.1.3";

		private static VFiXPlugin _instance;

		internal static VFiXPlugin Instance => _instance;

		private void Awake()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			SingletonHelper.Assign<VFiXPlugin>(ref _instance, this);
			Log.Init(((BaseUnityPlugin)this).Logger);
			FileCacheManager.Init();
			GrandparentPreSpawnEffectFix.Init();
			PooledEffectCleanupSoundFix.Init();
			stopwatch.Stop();
			Log.Message_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalMilliseconds:F0}ms");
		}

		private void OnDestroy()
		{
			SingletonHelper.Unassign<VFiXPlugin>(ref _instance, this);
		}
	}
}
namespace VFiX.PooledEffectStart
{
	public sealed class ApplyForceOnStartRestarter : MonoBehaviour, IEffectRestarter
	{
		private ApplyForceOnStart _applyForceOnStart;

		private void Awake()
		{
			_applyForceOnStart = ((Component)this).GetComponent<ApplyForceOnStart>();
		}

		void IEffectRestarter.Restart()
		{
			if (Object.op_Implicit((Object)(object)_applyForceOnStart))
			{
				_applyForceOnStart.Start();
			}
		}
	}
	public sealed class ApplyTorqueOnStartRestarter : MonoBehaviour, IEffectRestarter
	{
		private ApplyTorqueOnStart _applyTorqueOnStart;

		private void Awake()
		{
			_applyTorqueOnStart = ((Component)this).GetComponent<ApplyTorqueOnStart>();
		}

		void IEffectRestarter.Restart()
		{
			if (Object.op_Implicit((Object)(object)_applyTorqueOnStart))
			{
				_applyTorqueOnStart.Start();
			}
		}
	}
	public class CoinBehaviorRestarter : MonoBehaviour, IEffectRestarter
	{
		private CoinBehavior _coinBehavior;

		private void Awake()
		{
			_coinBehavior = ((Component)this).GetComponent<CoinBehavior>();
		}

		void IEffectRestarter.Restart()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_coinBehavior))
			{
				return;
			}
			CoinTier[] coinTiers = _coinBehavior.coinTiers;
			for (int i = 0; i < coinTiers.Length; i++)
			{
				ParticleSystem particleSystem = coinTiers[i].particleSystem;
				if (Object.op_Implicit((Object)(object)particleSystem))
				{
					EmissionModule emission = particleSystem.emission;
					((EmissionModule)(ref emission)).enabled = false;
					particleSystem.Stop();
					particleSystem.Clear();
					((Component)particleSystem).gameObject.SetActive(false);
				}
			}
			_coinBehavior.Start();
		}
	}
	public sealed class EffectPassArgsToLocalTokenRestarter : MonoBehaviour, IEffectRestarter
	{
		private EffectPassArgsToLocalToken _effectPassArgsToLocalToken;

		private void Awake()
		{
			_effectPassArgsToLocalToken = ((Component)this).GetComponent<EffectPassArgsToLocalToken>();
		}

		void IEffectRestarter.Restart()
		{
			if (Object.op_Implicit((Object)(object)_effectPassArgsToLocalToken))
			{
				_effectPassArgsToLocalToken.Start();
			}
		}
	}
	public sealed class EffectRestarterController : MonoBehaviour
	{
		private EffectComponent _effectComponent;

		private Rigidbody[] _rigidbodies = Array.Empty<Rigidbody>();

		private IEffectRestarter[] _restarters = Array.Empty<IEffectRestarter>();

		private Vector3 _originalScale = Vector3.one;

		private void Awake()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			_effectComponent = ((Component)this).GetComponent<EffectComponent>();
			if (Object.op_Implicit((Object)(object)_effectComponent))
			{
				EffectComponent effectComponent = _effectComponent;
				effectComponent.OnEffectComponentReset = (Action<bool>)Delegate.Combine(effectComponent.OnEffectComponentReset, new Action<bool>(onEffectComponentReset));
			}
			_rigidbodies = ((Component)this).GetComponentsInChildren<Rigidbody>(true);
			_restarters = ((Component)this).GetComponentsInChildren<IEffectRestarter>(true);
			_originalScale = ((Component)this).transform.localScale;
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)_effectComponent))
			{
				EffectComponent effectComponent = _effectComponent;
				effectComponent.OnEffectComponentReset = (Action<bool>)Delegate.Remove(effectComponent.OnEffectComponentReset, new Action<bool>(onEffectComponentReset));
			}
		}

		private void onEffectComponentReset(bool hasEffectData)
		{
			//IL_0025: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			if (((Component)this).gameObject.activeSelf)
			{
				return;
			}
			if (!hasEffectData || !_effectComponent.applyScale)
			{
				((Component)this).transform.localScale = _originalScale;
			}
			Rigidbody[] rigidbodies = _rigidbodies;
			foreach (Rigidbody val in rigidbodies)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					val.velocity = Vector3.zero;
					val.angularVelocity = Vector3.zero;
				}
			}
			IEffectRestarter[] restarters = _restarters;
			foreach (IEffectRestarter effectRestarter in restarters)
			{
				if (effectRestarter != null)
				{
					Behaviour val2 = (Behaviour)((effectRestarter is Behaviour) ? effectRestarter : null);
					if (val2 == null || (Object.op_Implicit((Object)(object)val2) && val2.enabled))
					{
						effectRestarter.Restart();
					}
				}
			}
		}
	}
	public sealed class ExplodeRigidbodiesOnStartRestarter : MonoBehaviour, IEffectRestarter
	{
		private ExplodeRigidbodiesOnStart _explodeRigidbodiesOnStart;

		private void Awake()
		{
			_explodeRigidbodiesOnStart = ((Component)this).GetComponent<ExplodeRigidbodiesOnStart>();
		}

		void IEffectRestarter.Restart()
		{
			if (Object.op_Implicit((Object)(object)_explodeRigidbodiesOnStart))
			{
				_explodeRigidbodiesOnStart.Start();
			}
		}
	}
	public interface IEffectRestarter
	{
		void Restart();
	}
	public sealed class ImpactEffectRestarter : MonoBehaviour, IEffectRestarter
	{
		private ImpactEffect _impactEffect;

		private void Awake()
		{
			_impactEffect = ((Component)this).GetComponent<ImpactEffect>();
		}

		void IEffectRestarter.Restart()
		{
			if (Object.op_Implicit((Object)(object)_impactEffect))
			{
				ParticleSystem[] particleSystems = _impactEffect.particleSystems;
				foreach (ParticleSystem obj in particleSystems)
				{
					obj.Stop();
					obj.Clear();
				}
				_impactEffect.Start();
			}
		}
	}
	internal sealed class ItemTakenOrbEffectRestarter : MonoBehaviour, IEffectRestarter
	{
		private ItemTakenOrbEffect orbEffect;

		private Color startColor;

		private Color endColor;

		private void Awake()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			orbEffect = ((Component)this).GetComponent<ItemTakenOrbEffect>();
			if (Object.op_Implicit((Object)(object)orbEffect.trailToColor))
			{
				startColor = orbEffect.trailToColor.startColor;
				endColor = orbEffect.trailToColor.endColor;
			}
		}

		public void Restart()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)orbEffect.trailToColor))
			{
				orbEffect.trailToColor.startColor = startColor;
				orbEffect.trailToColor.endColor = endColor;
			}
		}
	}
	public sealed class LightScaleFromParentRestarter : MonoBehaviour, IEffectRestarter
	{
		private LightScaleFromParent _lightScaleFromParent;

		private Light _light;

		private float _originalRange;

		private void Awake()
		{
			_lightScaleFromParent = ((Component)this).GetComponent<LightScaleFromParent>();
			Light val = default(Light);
			if (((Component)this).TryGetComponent<Light>(ref val))
			{
				_light = val;
				_originalRange = val.range;
			}
			else
			{
				((Behaviour)this).enabled = false;
			}
		}

		void IEffectRestarter.Restart()
		{
			if (Object.op_Implicit((Object)(object)_light))
			{
				_light.range = _originalRange;
			}
			else
			{
				Log.Warning("No light reference, light range will not be restored: " + Util.GetGameObjectHierarchyName(((Component)this).gameObject), "D:\\Git\\RoR2\\VFiX\\VFiX\\PooledEffectStart\\LightScaleFromParentRestarter.cs", "Restart", 41);
			}
			if (Object.op_Implicit((Object)(object)_lightScaleFromParent))
			{
				_lightScaleFromParent.Start();
			}
		}
	}
	public sealed class ParticleSystemColorFromEffectDataRestarter : MonoBehaviour, IEffectRestarter
	{
		private ParticleSystemColorFromEffectData _particleSystemColorFromEffectData;

		private void Awake()
		{
			_particleSystemColorFromEffectData = ((Component)this).GetComponent<ParticleSystemColorFromEffectData>();
		}

		void IEffectRestarter.Restart()
		{
			if (Object.op_Implicit((Object)(object)_particleSystemColorFromEffectData))
			{
				ParticleSystem[] particleSystems = _particleSystemColorFromEffectData.particleSystems;
				foreach (ParticleSystem obj in particleSystems)
				{
					obj.Stop();
					obj.Clear();
				}
				_particleSystemColorFromEffectData.Start();
			}
		}
	}
	public sealed class ParticleSystemRandomColorRestarter : MonoBehaviour, IEffectRestarter
	{
		private ParticleSystemRandomColor _particleSystemRandomColor;

		private void Awake()
		{
			_particleSystemRandomColor = ((Component)this).GetComponent<ParticleSystemRandomColor>();
		}

		void IEffectRestarter.Restart()
		{
			if (Object.op_Implicit((Object)(object)_particleSystemRandomColor))
			{
				_particleSystemRandomColor.Awake();
			}
		}
	}
	internal sealed class PickupTakenOrbEffectRestarter : MonoBehaviour, IEffectRestarter
	{
		private PickupTakenOrbEffect orbEffect;

		private Color startColor;

		private Color endColor;

		private void Awake()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			orbEffect = ((Component)this).GetComponent<PickupTakenOrbEffect>();
			if (Object.op_Implicit((Object)(object)orbEffect.trailToColor))
			{
				startColor = orbEffect.trailToColor.startColor;
				endColor = orbEffect.trailToColor.endColor;
			}
		}

		public void Restart()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)orbEffect.trailToColor))
			{
				orbEffect.trailToColor.startColor = startColor;
				orbEffect.trailToColor.endColor = endColor;
			}
		}
	}
	internal static class PooledEffectStartFix
	{
		private static bool GetEffectIndicesToCheck(int cacheKey, List<EffectIndex> dest)
		{
			//IL_0019: 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_0074: Invalid comparison between Unknown and I4
			//IL_001c: 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_006c: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			if (FileCacheManager.EffectRestarterIndices.TryRead(cacheKey, out var value))
			{
				ListUtils.AddRange<EffectIndex>(dest, value);
				return true;
			}
			for (EffectIndex val = (EffectIndex)0; (int)val < EffectCatalog.effectCount; val = (EffectIndex)(val + 1))
			{
				EffectDef effectDef = EffectCatalog.GetEffectDef(val);
				if (effectDef != null)
				{
					AssetOrDirectReference<GameObject> prefabAssetOrDirectReference = effectDef._prefabAssetOrDirectReference;
					if (prefabAssetOrDirectReference != null && (Object.op_Implicit((Object)(object)prefabAssetOrDirectReference.directRef) || (prefabAssetOrDirectReference.address != null && ((AssetReference)prefabAssetOrDirectReference.address).RuntimeKeyIsValid())) && effectDef.shouldPool)
					{
						dest.Add(val);
					}
				}
			}
			return false;
		}

		[SystemInitializer(new Type[] { typeof(EffectCatalog) })]
		private static void Init()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			HashCode hashCode = default(HashCode);
			for (EffectIndex val = (EffectIndex)0; (int)val < EffectCatalog.effectCount; val = (EffectIndex)(val + 1))
			{
				hashCode.Add(EffectCatalog.GetEffectDef(val).prefabName);
			}
			foreach (string key in Chainloader.PluginInfos.Keys)
			{
				hashCode.Add(key);
			}
			int effectsCacheKey = hashCode.ToHashCode();
			List<EffectIndex> list = new List<EffectIndex>(EffectCatalog.effectCount);
			bool isCached = GetEffectIndicesToCheck(effectsCacheKey, list);
			List<EffectDef> modifiedEffectDefs = new List<EffectDef>(list.Count);
			ParallelCoroutine val2 = new ParallelCoroutine();
			foreach (EffectIndex item in list)
			{
				EffectDef effectDef = EffectCatalog.GetEffectDef(item);
				AssetOrDirectReference<GameObject> prefabAssetOrDirectReference = effectDef._prefabAssetOrDirectReference;
				if (Object.op_Implicit((Object)(object)prefabAssetOrDirectReference.directRef))
				{
					handleEffectPrefab(prefabAssetOrDirectReference.directRef);
				}
				else if (prefabAssetOrDirectReference.address != null && ((AssetReference)prefabAssetOrDirectReference.address).RuntimeKeyIsValid())
				{
					val2.Add(handleEffectPrefabAsync(prefabAssetOrDirectReference.address));
				}
				bool handleEffectPrefab(GameObject effectPrefab)
				{
					int num = 0 + tryAddRestarters<LightScaleFromParent, LightScaleFromParentRestarter>() + tryAddRestarters<ImpactEffect, ImpactEffectRestarter>() + tryAddRestarters<ParticleSystemColorFromEffectData, ParticleSystemColorFromEffectDataRestarter>() + tryAddRestarters<CoinBehavior, CoinBehaviorRestarter>() + tryAddRestarters<VelocityRandomOnStart, VelocityRandomOnStartRestarter>() + tryAddRestarters<ParticleSystemRandomColor, ParticleSystemRandomColorRestarter>() + tryAddRestarters<ApplyTorqueOnStart, ApplyTorqueOnStartRestarter>() + tryAddRestarters<ApplyForceOnStart, ApplyForceOnStartRestarter>() + tryAddRestarters<ExplodeRigidbodiesOnStart, ExplodeRigidbodiesOnStartRestarter>() + tryAddRestarters<SetRandomRotation, SetRandomRotationRestarter>() + tryAddRestarters<EffectPassArgsToLocalToken, EffectPassArgsToLocalTokenRestarter>() + tryAddRestarters<ItemTakenOrbEffect, ItemTakenOrbEffectRestarter>() + tryAddRestarters<PickupTakenOrbEffect, PickupTakenOrbEffectRestarter>() + tryAddRestarters<TemporaryVisualEffect, TemporaryVisualEffectRestarter>();
					if (num > 0)
					{
						UnityObjectExtensions.EnsureComponent<EffectRestarterController>(effectPrefab);
						modifiedEffectDefs.Add(effectDef);
					}
					return num > 0;
					int tryAddRestarters<TComponent, TRestarter>() where TComponent : Component where TRestarter : Component, IEffectRestarter
					{
						int num2 = 0;
						TComponent[] componentsInChildren = effectPrefab.GetComponentsInChildren<TComponent>(true);
						for (int i = 0; i < componentsInChildren.Length; i++)
						{
							UnityObjectExtensions.EnsureComponent<TRestarter>(((Component)componentsInChildren[i]).gameObject);
							num2++;
						}
						return num2;
					}
				}
				IEnumerator handleEffectPrefabAsync(AssetReferenceT<GameObject> effectPrefabReference)
				{
					AsyncOperationHandle<GameObject> effectPrefabLoad = AssetAsyncReferenceManager<GameObject>.LoadAsset(effectPrefabReference, (AsyncReferenceHandleUnloadType)2);
					yield return effectPrefabLoad;
					bool flag = false;
					if (effectPrefabLoad.IsValid() && (int)effectPrefabLoad.Status == 1)
					{
						flag = handleEffectPrefab(effectPrefabLoad.Result);
					}
					if (!flag)
					{
						AssetAsyncReferenceManager<GameObject>.UnloadAsset(effectPrefabReference);
					}
				}
			}
			((MonoBehaviour)RoR2Application.instance).StartCoroutine(runEffectPrefabsLoad(val2));
			IEnumerator runEffectPrefabsLoad(ParallelCoroutine effectPrefabsLoadCoroutine)
			{
				while (effectPrefabsLoadCoroutine.MoveNext())
				{
					yield return effectPrefabsLoadCoroutine.Current;
				}
				if (!isCached)
				{
					int count = modifiedEffectDefs.Count;
					EffectIndex[] value = (EffectIndex[])(object)new EffectIndex[count];
					for (int i = 0; i < count; i++)
					{
						value[i] = (EffectIndex)(int)modifiedEffectDefs[i].index;
					}
					FileCacheManager.EffectRestarterIndices.Write(in value, effectsCacheKey);
				}
			}
		}

		[Conditional("DEBUG")]
		private static void logUnhandledStartComponents(GameObject effectPrefab)
		{
			MonoBehaviour[] componentsInChildren = effectPrefab.GetComponentsInChildren<MonoBehaviour>();
			foreach (MonoBehaviour val in componentsInChildren)
			{
				Type type = ((object)val).GetType();
				if (type == typeof(EffectComponent) || type == typeof(DestroyOnTimer) || type == typeof(DestroyOnParticleEnd) || type == typeof(AnimateShaderAlpha) || type == typeof(LightScaleFromParent) || type == typeof(RTPCController) || type == typeof(TeamFilter) || type == typeof(ScaleParticleSystemDuration) || type == typeof(RotateObject) || type == typeof(AlignToNormal) || type == typeof(OmniEffect) || type == typeof(ImpactEffect) || type == typeof(ParticleSystemColorFromEffectData) || type == typeof(LaserPointer) || type == typeof(CoinBehavior) || type == typeof(VelocityRandomOnStart) || type == typeof(ParticleSystemRandomColor) || type == typeof(RigidbodyStickOnImpact) || type == typeof(ApplyTorqueOnStart) || type == typeof(ApplyForceOnStart) || type == typeof(ExplodeRigidbodiesOnStart) || type == typeof(MaintainRotation) || type == typeof(RotateItem) || type == typeof(SetRandomRotation) || type == typeof(Tracer) || type == typeof(BeamPointsFromTransforms) || type == typeof(LineBetweenTransforms) || type == typeof(MultiPointBezierCurveLine) || type == typeof(AddOverlayToReferencedObject) || type == typeof(TemporaryOverlay) || type == typeof(RendererColorFromEffectData) || type == typeof(EffectRetimer) || type == typeof(EffectPassArgsToLocalToken) || type == typeof(RotateIfMoving) || type == typeof(PickRandomObjectOnAwake) || type == typeof(PlatformToggle) || type == typeof(NetworkParent) || type == typeof(RunPresenceRendererToggle) || type == typeof(TemporaryVisualEffect) || type == typeof(ItemTakenOrbEffect) || type == typeof(PickupTakenOrbEffect) || type == typeof(ScaleParticleDurationFromEffectData))
				{
					continue;
				}
				bool num = type.GetMethod("Awake", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null || type.GetMethod("Start", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null;
				bool flag = type.GetMethod("OnEnable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null;
				if (num && !flag)
				{
					string text = "Init-only component " + type.FullName + " on " + ((Object)effectPrefab).name;
					if ((Object)(object)((Component)val).transform != (Object)(object)effectPrefab.transform)
					{
						text = text + ", at " + Util.BuildPrefabTransformPath(effectPrefab.transform, ((Component)val).transform, false, true);
					}
					Log.Info(text, "D:\\Git\\RoR2\\VFiX\\VFiX\\PooledEffectStart\\PooledEffectStartFix.cs", "logUnhandledStartComponents", 260);
				}
			}
		}
	}
	public sealed class RotateIfMovingRestarter : MonoBehaviour, IEffectRestarter
	{
		private RotateIfMoving _rotateIfMoving;

		private void Awake()
		{
			_rotateIfMoving = ((Component)this).GetComponent<RotateIfMoving>();
		}

		void IEffectRestarter.Restart()
		{
			if (Object.op_Implicit((Object)(object)_rotateIfMoving))
			{
				_rotateIfMoving.Start();
			}
		}
	}
	public sealed class SetRandomRotationRestarter : MonoBehaviour, IEffectRestarter
	{
		private SetRandomRotation _setRandomRotation;

		private Vector3 _originalEulerAngles;

		private void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			_setRandomRotation = ((Component)this).GetComponent<SetRandomRotation>();
			_originalEulerAngles = ((Component)this).transform.localEulerAngles;
		}

		void IEffectRestarter.Restart()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_setRandomRotation))
			{
				((Component)this).transform.localEulerAngles = _originalEulerAngles;
				_setRandomRotation.Start();
			}
		}
	}
	public sealed class TemporaryVisualEffectRestarter : MonoBehaviour, IEffectRestarter
	{
		private TemporaryVisualEffect _temporaryVisualEffect;

		private void Awake()
		{
			_temporaryVisualEffect = ((Component)this).GetComponent<TemporaryVisualEffect>();
		}

		public void Restart()
		{
			_temporaryVisualEffect.RebuildVisualComponents();
		}
	}
	public sealed class VelocityRandomOnStartRestarter : MonoBehaviour, IEffectRestarter
	{
		private VelocityRandomOnStart _velocityRandomOnStart;

		private void Awake()
		{
			_velocityRandomOnStart = ((Component)this).GetComponent<VelocityRandomOnStart>();
		}

		void IEffectRestarter.Restart()
		{
			if (Object.op_Implicit((Object)(object)_velocityRandomOnStart))
			{
				_velocityRandomOnStart.Start();
			}
		}
	}
}
namespace VFiX.PooledEffectCleanup
{
	internal static class PooledEffectCleanupSoundFix
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_PreDestroyObject <0>__EffectPool_PreDestroyObject;
		}

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__EffectPool_PreDestroyObject;
			if (obj == null)
			{
				hook_PreDestroyObject val = EffectPool_PreDestroyObject;
				<>O.<0>__EffectPool_PreDestroyObject = val;
				obj = (object)val;
			}
			EffectPool.PreDestroyObject += (hook_PreDestroyObject)obj;
		}

		private static void EffectPool_PreDestroyObject(orig_PreDestroyObject orig, EffectPool self, EffectManagerHelper inKillObject)
		{
			orig.Invoke(self, inKillObject);
			AkTriggerHandler val = default(AkTriggerHandler);
			if (Object.op_Implicit((Object)(object)inKillObject) && ((Component)inKillObject).TryGetComponent<AkTriggerHandler>(ref val))
			{
				val.triggerList.Clear();
			}
		}
	}
}
namespace VFiX.GrandparentPreSpawnEffect
{
	internal static class GrandparentPreSpawnEffectFix
	{
		public static void Init()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			AssetAsyncReferenceManager<GameObject>.LoadAsset(RoR2_Base_Grandparent.GrandparentPreSpawnEffect_prefab, (AsyncReferenceHandleUnloadType)2, (AssetReferenceT<GameObject>)null).CallOnSuccess(delegate(GameObject grandparentPreSpawnEffect)
			{
				VFXAttributes val = default(VFXAttributes);
				if (grandparentPreSpawnEffect.TryGetComponent<VFXAttributes>(ref val))
				{
					val.DoNotPool = true;
				}
			});
			((ResourceAvailability)(ref EffectCatalog.availability)).CallWhenAvailable((Action)delegate
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Invalid comparison between Unknown and I4
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				EffectIndex val = EffectCatalog.FindEffectIndex("GrandparentPreSpawnEffect");
				if ((int)val != -1)
				{
					EffectCatalog.GetEffectDef(val).shouldPool = false;
				}
				else
				{
					Log.Warning("Failed to find EffectIndex for GrandparentPreSpawnEffect", "D:\\Git\\RoR2\\VFiX\\VFiX\\GrandparentPreSpawnEffect\\GrandparentPreSpawnEffectFix.cs", "Init", 30);
				}
			});
		}
	}
}
namespace VFiX.DitherFix
{
	internal static class ModelDitherFix
	{
		private static readonly int _FadeOn = Shader.PropertyToID("_FadeOn");

		[SystemInitializer(new Type[]
		{
			typeof(SkinCatalog),
			typeof(BodyCatalog),
			typeof(ItemDisplayRuleSet)
		})]
		private static void Init()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Invalid comparison between Unknown and I4
			//IL_003d: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			Stopwatch stopwatch = Stopwatch.StartNew();
			HashSet<string> loadedAssets = new HashSet<string>();
			HashSet<Material> handledMaterials = new HashSet<Material>();
			int numFixedMaterials = 0;
			ParallelCoroutine loadCoroutine = new ParallelCoroutine();
			for (SkinIndex val = (SkinIndex)0; (int)val < SkinCatalog.skinCount; val = (SkinIndex)(val + 1))
			{
				SkinDef skinDef = SkinCatalog.GetSkinDef(val);
				if (Object.op_Implicit((Object)(object)skinDef))
				{
					var (val2, val3) = skinDef.GetSkinParams();
					if (Object.op_Implicit((Object)(object)val3))
					{
						loadCoroutine.Add(handleSkinParamsAsync(val3));
					}
					else if (val2 != null && ((AssetReference)val2).RuntimeKeyIsValid() && loadedAssets.Add(((AssetReference)val2).RuntimeKey.ToString()))
					{
						loadCoroutine.Add(loadSkinParamsAsync(val2));
					}
				}
			}
			foreach (ItemDisplayRuleSet instances in ItemDisplayRuleSet.instancesList)
			{
				NamedRuleGroup[] namedItemRuleGroups = instances.namedItemRuleGroups;
				for (int i = 0; i < namedItemRuleGroups.Length; i++)
				{
					NamedRuleGroup val4 = namedItemRuleGroups[i];
					handleDisplayRuleGroup(in val4.displayRuleGroup);
				}
				KeyAssetRuleGroup[] keyAssetRuleGroups = instances.keyAssetRuleGroups;
				for (int i = 0; i < keyAssetRuleGroups.Length; i++)
				{
					KeyAssetRuleGroup val5 = keyAssetRuleGroups[i];
					handleDisplayRuleGroup(in val5.displayRuleGroup);
				}
			}
			((MonoBehaviour)RoR2Application.instance).StartCoroutine(runLoadCoroutine());
			IEnumerator handleDisplayPrefabAsync(GameObject displayPrefab)
			{
				RendererInfo[] array = Array.Empty<RendererInfo>();
				ItemDisplay val6 = default(ItemDisplay);
				if (displayPrefab.TryGetComponent<ItemDisplay>(ref val6) && val6.rendererInfos != null && val6.rendererInfos.Length != 0)
				{
					array = val6.rendererInfos;
				}
				if (array.Length != 0)
				{
					yield return handleRendererInfosAsync(val6.rendererInfos);
				}
			}
			void handleDisplayRuleGroup(in DisplayRuleGroup displayRuleGroup)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: 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_0038: 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_0065: 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)
				DisplayRuleGroup val6 = displayRuleGroup;
				if (!((DisplayRuleGroup)(ref val6)).isEmpty)
				{
					ItemDisplayRule[] rules = displayRuleGroup.rules;
					foreach (ItemDisplayRule val7 in rules)
					{
						if (Object.op_Implicit((Object)(object)val7.followerPrefab))
						{
							loadCoroutine.Add(handleDisplayPrefabAsync(val7.followerPrefab));
						}
						else if (val7.followerPrefabAddress != null && ((AssetReference)val7.followerPrefabAddress).RuntimeKeyIsValid() && loadedAssets.Add(((AssetReference)val7.followerPrefabAddress).RuntimeKey.ToString()))
						{
							loadCoroutine.Add(loadDisplayPrefabAsync((AssetReferenceT<GameObject>)(object)val7.followerPrefabAddress));
						}
					}
				}
			}
			bool handleMaterial(Material material)
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)material))
				{
					return false;
				}
				Shader shader = material.shader;
				if (!Object.op_Implicit((Object)(object)shader))
				{
					return false;
				}
				if (!handledMaterials.Add(material))
				{
					return false;
				}
				bool flag = false;
				LocalKeywordSpace keywordSpace = shader.keywordSpace;
				LocalKeyword val6 = ((LocalKeywordSpace)(ref keywordSpace)).FindKeyword("DITHER");
				if (((LocalKeyword)(ref val6)).isValid && !material.IsKeywordEnabled(ref val6))
				{
					material.EnableKeyword(ref val6);
					flag = true;
				}
				if (material.HasInt(_FadeOn) && material.GetInt(_FadeOn) == 0)
				{
					material.SetInt(_FadeOn, 1);
					flag = true;
				}
				if (flag)
				{
					numFixedMaterials++;
				}
				return flag;
			}
			IEnumerator handleRendererInfosAsync(RendererInfo[] rendererInfos)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Expected O, but got Unknown
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: 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_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				ParallelCoroutine val6 = new ParallelCoroutine();
				foreach (RendererInfo val7 in rendererInfos)
				{
					if (Object.op_Implicit((Object)(object)val7.defaultMaterial))
					{
						handleMaterial(val7.defaultMaterial);
					}
					else if (val7.defaultMaterialAddress != null && ((AssetReference)val7.defaultMaterialAddress).RuntimeKeyIsValid() && loadedAssets.Add(((AssetReference)val7.defaultMaterialAddress).RuntimeKey.ToString()))
					{
						val6.Add(loadMaterialAsync(val7.defaultMaterialAddress));
					}
				}
				return (IEnumerator)val6;
			}
			IEnumerator handleSkinParamsAsync(SkinDefParams skinDefParams)
			{
				return handleRendererInfosAsync(skinDefParams.rendererInfos);
			}
			IEnumerator loadDisplayPrefabAsync(AssetReferenceT<GameObject> displayPrefabReference)
			{
				AsyncOperationHandle<GameObject> displayPrefabLoad = AssetAsyncReferenceManager<GameObject>.LoadAsset(displayPrefabReference, (AsyncReferenceHandleUnloadType)0);
				yield return displayPrefabLoad;
				if (displayPrefabLoad.IsValid() && (int)displayPrefabLoad.Status == 1 && Object.op_Implicit((Object)(object)displayPrefabLoad.Result))
				{
					yield return handleDisplayPrefabAsync(displayPrefabLoad.Result);
				}
			}
			IEnumerator loadMaterialAsync(AssetReferenceT<Material> materialReference)
			{
				AsyncOperationHandle<Material> materialLoad = AssetAsyncReferenceManager<Material>.LoadAsset(materialReference, (AsyncReferenceHandleUnloadType)2);
				yield return materialLoad;
				bool flag = false;
				if (materialLoad.IsValid() && (int)materialLoad.Status == 1 && Object.op_Implicit((Object)(object)materialLoad.Result))
				{
					flag = handleMaterial(materialLoad.Result);
				}
				if (!flag)
				{
					AssetAsyncReferenceManager<Material>.UnloadAsset(materialReference);
				}
			}
			IEnumerator loadSkinParamsAsync(AssetReferenceT<SkinDefParams> skinParamsReference)
			{
				AsyncOperationHandle<SkinDefParams> skinParamsLoad = AssetAsyncReferenceManager<SkinDefParams>.LoadAsset(skinParamsReference, (AsyncReferenceHandleUnloadType)0);
				yield return skinParamsLoad;
				if (skinParamsLoad.IsValid() && (int)skinParamsLoad.Status == 1 && Object.op_Implicit((Object)(object)skinParamsLoad.Result))
				{
					yield return handleSkinParamsAsync(skinParamsLoad.Result);
				}
			}
			IEnumerator runLoadCoroutine()
			{
				yield return loadCoroutine;
				Log.Info($"Fixed dithering for {numFixedMaterials}/{handledMaterials.Count} material(s) ({stopwatch.Elapsed.TotalMilliseconds:0}ms)", "D:\\Git\\RoR2\\VFiX\\VFiX\\DitherFix\\ModelDitherFix.cs", "Init", 223);
				stopwatch.Stop();
				handledMaterials.Clear();
				loadedAssets.Clear();
			}
		}
	}
}
namespace VFiX.Cache
{
	internal static class FileCacheManager
	{
		private static readonly string _cacheDirectory = Path.Combine(Application.persistentDataPath, "Gorakh.VFiX", "cache");

		private static readonly string _cacheVersionFilePath = Path.Combine(_cacheDirectory, "version");

		private static string _gameVersionString;

		public static GenericCache<EffectIndex[], ArraySerializer<EffectIndex, EffectIndexSerializer>> EffectRestarterIndices = new GenericCache<EffectIndex[], ArraySerializer<EffectIndex, EffectIndexSerializer>>(Path.Combine(_cacheDirectory, "effect-restarter-indices"), new ArraySerializer<EffectIndex, EffectIndexSerializer>(default(EffectIndexSerializer)));

		public static string GetGameVersionString()
		{
			if (_gameVersionString == null)
			{
				FieldInfo field = typeof(AutomatedBuildVersion).GetField("buildVersionString", BindingFlags.Static | BindingFlags.Public);
				string text2;
				if (field != null && field.GetValue(null) is string text && !string.IsNullOrWhiteSpace(text))
				{
					text2 = text;
				}
				else
				{
					Log.Error("Failed to find field AutomatedBuildVersion.buildVersionString, using compile constant build version: 1210", "D:\\Git\\RoR2\\VFiX\\VFiX\\Cache\\FileCacheManager.cs", "GetGameVersionString", 34);
					text2 = "1210";
				}
				_gameVersionString = Application.version + "#" + text2;
			}
			return _gameVersionString;
		}

		private static bool hasCacheForVersion(string version)
		{
			if (!File.Exists(_cacheVersionFilePath))
			{
				return false;
			}
			try
			{
				return File.ReadAllText(_cacheVersionFilePath) == version;
			}
			catch (Exception arg)
			{
				Log.Error_NoCallerPrefix($"Failed to read cache version, all caches will be regenerated: {arg}");
				return false;
			}
		}

		public static void Init()
		{
			string gameVersionString = GetGameVersionString();
			Directory.CreateDirectory(_cacheDirectory);
			if (!hasCacheForVersion(gameVersionString))
			{
				ClearCache();
				File.WriteAllText(_cacheVersionFilePath, gameVersionString);
			}
		}

		private static int ClearCache()
		{
			int num = 0;
			foreach (string item in Directory.EnumerateFiles(_cacheDirectory))
			{
				try
				{
					File.Delete(item);
					num++;
				}
				catch (Exception arg)
				{
					Log.Error_NoCallerPrefix($"Failed to delete cache file '{Path.GetFileName(item)}': {arg}");
				}
			}
			return num;
		}

		[ConCommand(commandName = "vfix_clear_cahe", helpText = "Deletes all cache files used by VFiX")]
		private static void CCClearCache(ConCommandArgs args)
		{
			int num = ClearCache();
			((ConCommandArgs)(ref args)).Log((object)$"Deleted {num} cache file(s)");
		}
	}
	internal readonly struct GenericCache<T, TSerializer> where TSerializer : IBinarySerializer<T>
	{
		private readonly string _filePath;

		private readonly TSerializer _serializer;

		public GenericCache(string filePath, TSerializer serializer)
		{
			_filePath = filePath;
			_serializer = serializer;
		}

		public bool TryRead(int keyHash, [MaybeNullWhen(false)] out T value)
		{
			if (!File.Exists(_filePath))
			{
				value = default(T);
				return false;
			}
			try
			{
				using FileStream input = File.Open(_filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
				using BinaryReader binaryReader = new BinaryReader(input);
				if (binaryReader.ReadInt32() == keyHash)
				{
					value = _serializer.Deserialize(binaryReader);
					return true;
				}
				value = default(T);
				return false;
			}
			catch (Exception arg)
			{
				Log.Error_NoCallerPrefix($"Failed to read from cache file {Path.GetFileName(_filePath)}: {arg}");
				value = default(T);
				return false;
			}
		}

		public void Write(in T value, int keyHash)
		{
			try
			{
				using FileStream output = File.Open(_filePath, FileMode.Create, FileAccess.Write, FileShare.None);
				using BinaryWriter binaryWriter = new BinaryWriter(output);
				binaryWriter.Write(keyHash);
				_serializer.Serialize(binaryWriter, in value);
			}
			catch (Exception arg)
			{
				Log.Error_NoCallerPrefix($"Failed to write to cache file {Path.GetFileName(_filePath)}: {arg}");
			}
		}
	}
}
namespace VFiX.Cache.Serialization
{
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal readonly struct AssetReferenceSerializer : IBinarySerializer<AssetReference>
	{
		public void Serialize(BinaryWriter writer, in AssetReference value)
		{
			if (value.RuntimeKey is string value2)
			{
				writer.Write(value2);
			}
			else
			{
				writer.Write(string.Empty);
			}
		}

		public AssetReference Deserialize(BinaryReader reader)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			return new AssetReference(reader.ReadString());
		}

		void IBinarySerializer<AssetReference>.Serialize(BinaryWriter writer, in AssetReference value)
		{
			Serialize(writer, in value);
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal readonly struct AssetReferenceSerializer<T> : IBinarySerializer<AssetReferenceT<T>> where T : Object
	{
		public void Serialize(BinaryWriter writer, in AssetReferenceT<T> value)
		{
			if (((AssetReference)value).RuntimeKey is string value2)
			{
				writer.Write(value2);
			}
			else
			{
				writer.Write(string.Empty);
			}
		}

		public AssetReferenceT<T> Deserialize(BinaryReader reader)
		{
			return new AssetReferenceT<T>(reader.ReadString());
		}

		void IBinarySerializer<AssetReferenceT<T>>.Serialize(BinaryWriter writer, in AssetReferenceT<T> value)
		{
			Serialize(writer, in value);
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal readonly struct EffectIndexSerializer : IBinarySerializer<EffectIndex>
	{
		public void Serialize(BinaryWriter writer, in EffectIndex value)
		{
			writer.Write((int)value);
		}

		public EffectIndex Deserialize(BinaryReader reader)
		{
			return (EffectIndex)reader.ReadInt32();
		}

		void IBinarySerializer<EffectIndex>.Serialize(BinaryWriter writer, in EffectIndex value)
		{
			Serialize(writer, in value);
		}
	}
	internal interface IBinarySerializer<T>
	{
		void Serialize(BinaryWriter writer, in T value);

		T Deserialize(BinaryReader reader);
	}
	internal readonly struct ArraySerializer<T, TElementSerializer> : IBinarySerializer<T[]> where TElementSerializer : IBinarySerializer<T>
	{
		private readonly TElementSerializer _elementSerializer;

		public ArraySerializer(TElementSerializer elementSerializer)
		{
			_elementSerializer = elementSerializer;
		}

		public void Serialize(BinaryWriter writer, in T[] array)
		{
			if (array == null)
			{
				writer.Write(0);
				return;
			}
			writer.Write(array.Length);
			for (int i = 0; i < array.Length; i++)
			{
				_elementSerializer.Serialize(writer, in array[i]);
			}
		}

		public T[] Deserialize(BinaryReader reader)
		{
			int num = reader.ReadInt32();
			if (num == 0)
			{
				return Array.Empty<T>();
			}
			T[] array = new T[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = _elementSerializer.Deserialize(reader);
			}
			return array;
		}

		void IBinarySerializer<T[]>.Serialize(BinaryWriter writer, in T[] value)
		{
			Serialize(writer, in value);
		}
	}
}