Decompiled source of BirdieMod v1.3.4

BepInEx\plugins\BirdieMod\BirdieMod.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
internal static class BirdieGrantBridge
{
	private const string CommandMethodName = "System.Void PlayerInventory::BirdieCmdGrantItem(System.Int32)";

	private static bool initialized;

	private static float _nextRetry = -1f;

	private static ushort registeredCommandHash;

	private static Type mirrorNbType;

	private static Type mirrorReaderType;

	private static Type mirrorConnType;

	private static Type mirrorRpcType;

	private static Type mirrorRcdType;

	private static Type mirrorRctType;

	private static Type mirrorCmdMsgType;

	private static Type mirrorNcType;

	private static Type mirrorNwpType;

	private static Type mirrorNwExtType;

	private static Type mirrorNrExtType;

	private static MethodInfo mirrorRegisterDelegate;

	private static MethodInfo mirrorNcSend;

	private static MethodInfo mirrorWriterExtWriteInt;

	private static MethodInfo mirrorWriterPoolGet;

	private static MethodInfo mirrorWriterPoolReturn;

	private static MethodInfo mirrorWriterToArraySegment;

	private static MethodInfo mirrorReaderExtReadInt;

	private static PropertyInfo mirrorNbNetId;

	private static PropertyInfo mirrorNbComponentIndex;

	private static FieldInfo mirrorCmdNetId;

	private static FieldInfo mirrorCmdComponentIndex;

	private static FieldInfo mirrorCmdFunctionHash;

	private static FieldInfo mirrorCmdPayload;

	private static MethodInfo cachedServerTryAddItemMethod;

	private static Type cachedItemTypeEnumType;

	private static PropertyInfo cachedAllItemsProperty;

	private static MethodInfo cachedTryGetItemDataMethod;

	private static PropertyInfo cachedItemDataMaxUsesProperty;

	internal static bool IsReady()
	{
		if (initialized)
		{
			return registeredCommandHash != 0;
		}
		return false;
	}

	internal static void EnsureInitialized()
	{
		if (initialized)
		{
			return;
		}
		float time = Time.time;
		if (time < _nextRetry)
		{
			return;
		}
		_nextRetry = time + 2f;
		try
		{
			if (CollectReflectionCaches())
			{
				RegisterCommandHandler();
				if (registeredCommandHash != 0)
				{
					initialized = true;
					BirdieLog.Msg("[Birdie] Grant bridge ready.");
				}
			}
		}
		catch (Exception ex)
		{
			BirdieLog.Warning("[Birdie] Grant bridge init: " + ex.Message);
		}
	}

	internal static void RequestGrant(Component inventory, int itemTypeInt)
	{
		EnsureInitialized();
		if (registeredCommandHash == 0 || mirrorNbNetId == null || mirrorNbComponentIndex == null || mirrorCmdMsgType == null || mirrorNcSend == null || mirrorWriterExtWriteInt == null || mirrorWriterPoolGet == null || mirrorWriterPoolReturn == null || mirrorWriterToArraySegment == null)
		{
			BirdieLog.Warning("[Birdie] Item spawner: grant bridge not ready (reflection incomplete).");
			return;
		}
		try
		{
			uint num = (uint)mirrorNbNetId.GetValue(inventory, null);
			byte b = (byte)mirrorNbComponentIndex.GetValue(inventory, null);
			object obj = mirrorWriterPoolGet.Invoke(null, null);
			mirrorWriterExtWriteInt.Invoke(null, new object[2] { obj, itemTypeInt });
			ArraySegment<byte> arraySegment = (ArraySegment<byte>)mirrorWriterToArraySegment.Invoke(obj, null);
			object obj2 = Activator.CreateInstance(mirrorCmdMsgType);
			mirrorCmdNetId.SetValue(obj2, num);
			mirrorCmdComponentIndex.SetValue(obj2, b);
			mirrorCmdFunctionHash.SetValue(obj2, registeredCommandHash);
			mirrorCmdPayload.SetValue(obj2, arraySegment);
			mirrorNcSend.Invoke(null, new object[2] { obj2, 0 });
			mirrorWriterPoolReturn.Invoke(null, new object[1] { obj });
		}
		catch (Exception ex)
		{
			BirdieLog.Warning("[Birdie] Item spawner (client bridge): " + ex.Message);
		}
	}

	private static void ServerHandleGrantItem(object nbObj, object readerObj, object connObj)
	{
		try
		{
			if (nbObj == null || readerObj == null)
			{
				return;
			}
			if (mirrorReaderExtReadInt == null || cachedServerTryAddItemMethod == null || cachedItemTypeEnumType == null)
			{
				BirdieLog.Warning("[Birdie] Grant bridge server handler: reflection incomplete.");
				return;
			}
			int num = (int)mirrorReaderExtReadInt.Invoke(null, new object[1] { readerObj });
			object obj = Enum.ToObject(cachedItemTypeEnumType, num);
			int num2 = GetItemMaxUses(num);
			if (num2 <= 0)
			{
				num2 = 1;
			}
			if (!(bool)cachedServerTryAddItemMethod.Invoke(nbObj, new object[2] { obj, num2 }))
			{
				BirdieLog.Warning("[Birdie] Item spawner (bridge server): inventory full or item invalid.");
			}
		}
		catch (Exception ex)
		{
			BirdieLog.Warning("[Birdie] Grant bridge server handler: " + ex.Message);
		}
	}

	private static bool CollectReflectionCaches()
	{
		Assembly assembly = null;
		Assembly assembly2 = null;
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly3 in assemblies)
		{
			switch (assembly3.GetName().Name)
			{
			case "Mirror":
				assembly = assembly3;
				break;
			case "Assembly-CSharp":
			case "GameAssembly":
				assembly2 = assembly3;
				break;
			}
		}
		if (assembly == null || assembly2 == null)
		{
			return false;
		}
		mirrorNbType = assembly.GetType("Mirror.NetworkBehaviour");
		mirrorReaderType = assembly.GetType("Mirror.NetworkReader");
		mirrorConnType = assembly.GetType("Mirror.NetworkConnectionToClient");
		mirrorRpcType = assembly.GetType("Mirror.RemoteCalls.RemoteProcedureCalls");
		mirrorRcdType = assembly.GetType("Mirror.RemoteCalls.RemoteCallDelegate");
		mirrorRctType = assembly.GetType("Mirror.RemoteCalls.RemoteCallType");
		mirrorCmdMsgType = assembly.GetType("Mirror.CommandMessage");
		mirrorNcType = assembly.GetType("Mirror.NetworkClient");
		mirrorNwpType = assembly.GetType("Mirror.NetworkWriterPool");
		mirrorNwExtType = assembly.GetType("Mirror.NetworkWriterExtensions");
		mirrorNrExtType = assembly.GetType("Mirror.NetworkReaderExtensions");
		if (mirrorNbType == null || mirrorReaderType == null || mirrorConnType == null || mirrorRpcType == null || mirrorRcdType == null || mirrorRctType == null || mirrorCmdMsgType == null || mirrorNcType == null || mirrorNwpType == null || mirrorNwExtType == null || mirrorNrExtType == null)
		{
			return false;
		}
		mirrorRegisterDelegate = mirrorRpcType.GetMethod("RegisterDelegate", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		MethodInfo method = mirrorNcType.GetMethod("Send", BindingFlags.Static | BindingFlags.Public);
		if (method != null)
		{
			mirrorNcSend = method.MakeGenericMethod(mirrorCmdMsgType);
		}
		mirrorWriterExtWriteInt = mirrorNwExtType.GetMethod("WriteInt", BindingFlags.Static | BindingFlags.Public);
		mirrorWriterPoolGet = mirrorNwpType.GetMethod("Get", BindingFlags.Static | BindingFlags.Public);
		mirrorWriterPoolReturn = mirrorNwpType.GetMethod("Return", BindingFlags.Static | BindingFlags.Public);
		Type type = assembly.GetType("Mirror.NetworkWriter");
		if (type != null)
		{
			mirrorWriterToArraySegment = type.GetMethod("ToArraySegment", BindingFlags.Instance | BindingFlags.Public);
		}
		mirrorReaderExtReadInt = mirrorNrExtType.GetMethod("ReadInt", BindingFlags.Static | BindingFlags.Public);
		mirrorNbNetId = mirrorNbType.GetProperty("netId", BindingFlags.Instance | BindingFlags.Public);
		mirrorNbComponentIndex = mirrorNbType.GetProperty("ComponentIndex", BindingFlags.Instance | BindingFlags.Public);
		mirrorCmdNetId = mirrorCmdMsgType.GetField("netId");
		mirrorCmdComponentIndex = mirrorCmdMsgType.GetField("componentIndex");
		mirrorCmdFunctionHash = mirrorCmdMsgType.GetField("functionHash");
		mirrorCmdPayload = mirrorCmdMsgType.GetField("payload");
		Type type2 = assembly2.GetType("PlayerInventory");
		cachedItemTypeEnumType = assembly2.GetType("ItemType");
		if (type2 != null)
		{
			cachedServerTryAddItemMethod = type2.GetMethod("ServerTryAddItem", BindingFlags.Instance | BindingFlags.Public);
		}
		Type type3 = assembly2.GetType("ItemCollection");
		if (type3 != null)
		{
			cachedTryGetItemDataMethod = type3.GetMethod("TryGetItemData", BindingFlags.Instance | BindingFlags.Public);
		}
		Type type4 = assembly2.GetType("ItemData");
		if (type4 != null)
		{
			cachedItemDataMaxUsesProperty = type4.GetProperty("MaxUses", BindingFlags.Instance | BindingFlags.Public);
		}
		Type type5 = assembly2.GetType("GameManager");
		if (type5 != null)
		{
			cachedAllItemsProperty = type5.GetProperty("AllItems", BindingFlags.Static | BindingFlags.Public);
		}
		if (mirrorRegisterDelegate != null && mirrorNcSend != null && mirrorWriterExtWriteInt != null && mirrorWriterPoolGet != null && mirrorWriterToArraySegment != null && mirrorReaderExtReadInt != null && mirrorNbNetId != null && mirrorNbComponentIndex != null && mirrorCmdNetId != null && type2 != null && cachedServerTryAddItemMethod != null)
		{
			return cachedItemTypeEnumType != null;
		}
		return false;
	}

	private static void RegisterCommandHandler()
	{
		if (mirrorRegisterDelegate == null || mirrorRcdType == null || mirrorNbType == null || mirrorReaderType == null || mirrorConnType == null || mirrorRctType == null)
		{
			return;
		}
		Type type = null;
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		for (int i = 0; i < assemblies.Length; i++)
		{
			type = assemblies[i].GetType("PlayerInventory");
			if (type != null)
			{
				break;
			}
		}
		if (type == null)
		{
			BirdieLog.Warning("[Birdie] Grant bridge: PlayerInventory type not found.");
			return;
		}
		DynamicMethod dynamicMethod = new DynamicMethod("BirdieGrantItemCommandHandler", typeof(void), new Type[3] { mirrorNbType, mirrorReaderType, mirrorConnType }, typeof(BirdieGrantBridge).Module, skipVisibility: true);
		MethodInfo method = typeof(BirdieGrantBridge).GetMethod("ServerHandleGrantItem", BindingFlags.Static | BindingFlags.NonPublic);
		if (method == null)
		{
			BirdieLog.Warning("[Birdie] Grant bridge: ServerHandleGrantItem not found via reflection.");
			return;
		}
		ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
		iLGenerator.Emit(OpCodes.Ldarg_0);
		iLGenerator.Emit(OpCodes.Ldarg_1);
		iLGenerator.Emit(OpCodes.Ldarg_2);
		iLGenerator.Emit(OpCodes.Call, method);
		iLGenerator.Emit(OpCodes.Ret);
		Delegate @delegate = dynamicMethod.CreateDelegate(mirrorRcdType);
		object obj = Enum.Parse(mirrorRctType, "Command");
		registeredCommandHash = (ushort)mirrorRegisterDelegate.Invoke(null, new object[5] { type, "System.Void PlayerInventory::BirdieCmdGrantItem(System.Int32)", obj, @delegate, false });
		if (registeredCommandHash == 0)
		{
			BirdieLog.Warning("[Birdie] Grant bridge: RegisterDelegate returned hash 0 — may indicate a collision.");
		}
	}

	private static int GetItemMaxUses(int itemTypeInt)
	{
		try
		{
			if (cachedAllItemsProperty == null || cachedTryGetItemDataMethod == null || cachedItemDataMaxUsesProperty == null || cachedItemTypeEnumType == null)
			{
				return 1;
			}
			object value = cachedAllItemsProperty.GetValue(null, null);
			if (value == null)
			{
				return 1;
			}
			object obj = Enum.ToObject(cachedItemTypeEnumType, itemTypeInt);
			object[] array = new object[2] { obj, null };
			if (!(bool)cachedTryGetItemDataMethod.Invoke(value, array) || array[1] == null)
			{
				return 1;
			}
			return (int)cachedItemDataMaxUsesProperty.GetValue(array[1], null);
		}
		catch
		{
			return 1;
		}
	}
}
internal static class BirdieHostBridge
{
	private const string RpcMethodName = "System.Void PlayerInventory::BirdieCmdSyncHostConfig(System.Boolean,System.UInt64)";

	internal static bool IsUnderHostControl;

	internal static ulong ReceivedFeatureMask;

	private static bool initialized;

	private static float _nextRetry = -1f;

	private static ushort registeredRpcHash;

	internal static bool FlagExpandedSlotsForClient;

	private static Type mirrorNbType;

	private static Type mirrorReaderType;

	private static Type mirrorConnType;

	private static Type mirrorRpcType;

	private static Type mirrorRcdType;

	private static Type mirrorRctType;

	private static Type mirrorRpcMsgType;

	private static Type mirrorNsType;

	private static Type mirrorNwpType;

	private static Type mirrorNwExtType;

	private static Type mirrorNrExtType;

	private static MethodInfo mirrorRegisterDelegate;

	private static MethodInfo mirrorNsSendToAll;

	private static MethodInfo mirrorWriterExtWriteBool;

	private static MethodInfo mirrorWriterExtWriteULong;

	private static MethodInfo mirrorWriterPoolGet;

	private static MethodInfo mirrorWriterPoolReturn;

	private static MethodInfo mirrorWriterToArraySegment;

	private static MethodInfo mirrorReaderExtReadBool;

	private static MethodInfo mirrorReaderExtReadULong;

	private static PropertyInfo mirrorNbNetId;

	private static PropertyInfo mirrorNbComponentIndex;

	private static FieldInfo mirrorRpcNetId;

	private static FieldInfo mirrorRpcComponentIndex;

	private static FieldInfo mirrorRpcFunctionHash;

	private static FieldInfo mirrorRpcPayload;

	private static PropertyInfo cachedLocalPlayerInventoryProperty;

	internal static void EnsureHandlersRegistered()
	{
		if (initialized)
		{
			return;
		}
		float time = Time.time;
		if (time < _nextRetry)
		{
			return;
		}
		_nextRetry = time + 2f;
		try
		{
			if (CollectReflectionCaches())
			{
				RegisterRpcHandler();
				if (registeredRpcHash != 0)
				{
					initialized = true;
					BirdieLog.Msg("[Birdie] Host bridge ready.");
				}
			}
		}
		catch (Exception ex)
		{
			BirdieLog.Warning("[Birdie] Host bridge init: " + ex.Message);
		}
	}

	internal static void BroadcastToClients(bool active, ulong featureMask)
	{
		EnsureHandlersRegistered();
		try
		{
			Type type = mirrorNsType;
			if (type != null)
			{
				PropertyInfo property = type.GetProperty("active", BindingFlags.Static | BindingFlags.Public);
				if (property != null && !(bool)property.GetValue(null, null))
				{
					BirdieLog.Warning("[Birdie] Host bridge: NetworkServer is not active — cannot broadcast.");
					return;
				}
			}
		}
		catch (Exception ex)
		{
			BirdieLog.Warning("[Birdie] Host bridge (server check): " + ex.Message);
			return;
		}
		if (registeredRpcHash == 0 || mirrorNbNetId == null || mirrorNbComponentIndex == null || mirrorRpcMsgType == null || mirrorNsSendToAll == null || mirrorWriterExtWriteBool == null || mirrorWriterExtWriteULong == null || mirrorWriterPoolGet == null || mirrorWriterPoolReturn == null || mirrorWriterToArraySegment == null || cachedLocalPlayerInventoryProperty == null)
		{
			BirdieLog.Warning("[Birdie] Host bridge: broadcast not ready (reflection incomplete).");
			return;
		}
		try
		{
			object? value = cachedLocalPlayerInventoryProperty.GetValue(null, null);
			Component val = (Component)((value is Component) ? value : null);
			if ((Object)(object)val == (Object)null)
			{
				BirdieLog.Warning("[Birdie] Host bridge: LocalPlayerInventory is null.");
				return;
			}
			uint num = (uint)mirrorNbNetId.GetValue(val, null);
			byte b = (byte)mirrorNbComponentIndex.GetValue(val, null);
			ulong num2 = (active ? featureMask : ulong.MaxValue);
			object obj = mirrorWriterPoolGet.Invoke(null, null);
			mirrorWriterExtWriteBool.Invoke(null, new object[2] { obj, active });
			mirrorWriterExtWriteULong.Invoke(null, new object[2] { obj, num2 });
			ArraySegment<byte> arraySegment = (ArraySegment<byte>)mirrorWriterToArraySegment.Invoke(obj, null);
			object obj2 = Activator.CreateInstance(mirrorRpcMsgType);
			mirrorRpcNetId.SetValue(obj2, num);
			mirrorRpcComponentIndex.SetValue(obj2, b);
			mirrorRpcFunctionHash.SetValue(obj2, registeredRpcHash);
			mirrorRpcPayload.SetValue(obj2, arraySegment);
			mirrorNsSendToAll.Invoke(null, new object[2] { obj2, 0 });
			mirrorWriterPoolReturn.Invoke(null, new object[1] { obj });
		}
		catch (Exception ex2)
		{
			BirdieLog.Warning("[Birdie] Host bridge (broadcast): " + ex2.Message);
		}
	}

	private static void ClientHandleSyncHostConfig(object nbObj, object readerObj, object connObj)
	{
		try
		{
			if (readerObj == null)
			{
				return;
			}
			if (mirrorReaderExtReadBool == null || mirrorReaderExtReadULong == null)
			{
				BirdieLog.Warning("[Birdie] Host bridge client handler: reflection incomplete.");
				return;
			}
			bool flag = (bool)mirrorReaderExtReadBool.Invoke(null, new object[1] { readerObj });
			ulong num = (ulong)mirrorReaderExtReadULong.Invoke(null, new object[1] { readerObj });
			if (flag)
			{
				IsUnderHostControl = true;
				ReceivedFeatureMask = num;
				if ((num & 0x1000) != 0L)
				{
					FlagExpandedSlotsForClient = true;
				}
				BirdieLog.Msg("[Birdie] Host bridge: host control active, featureMask=0x" + num.ToString("X16"));
			}
			else
			{
				IsUnderHostControl = false;
				ReceivedFeatureMask = ulong.MaxValue;
				BirdieLog.Msg("[Birdie] Host bridge: host control deactivated (all features unlocked).");
			}
		}
		catch (Exception ex)
		{
			BirdieLog.Warning("[Birdie] Host bridge client handler: " + ex.Message);
		}
	}

	private static bool CollectReflectionCaches()
	{
		Assembly assembly = null;
		Assembly assembly2 = null;
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly3 in assemblies)
		{
			switch (assembly3.GetName().Name)
			{
			case "Mirror":
				assembly = assembly3;
				break;
			case "Assembly-CSharp":
			case "GameAssembly":
				assembly2 = assembly3;
				break;
			}
		}
		if (assembly == null || assembly2 == null)
		{
			return false;
		}
		mirrorNbType = assembly.GetType("Mirror.NetworkBehaviour");
		mirrorReaderType = assembly.GetType("Mirror.NetworkReader");
		mirrorConnType = assembly.GetType("Mirror.NetworkConnectionToClient");
		mirrorRpcType = assembly.GetType("Mirror.RemoteCalls.RemoteProcedureCalls");
		mirrorRcdType = assembly.GetType("Mirror.RemoteCalls.RemoteCallDelegate");
		mirrorRctType = assembly.GetType("Mirror.RemoteCalls.RemoteCallType");
		mirrorRpcMsgType = assembly.GetType("Mirror.RpcMessage");
		mirrorNsType = assembly.GetType("Mirror.NetworkServer");
		mirrorNwpType = assembly.GetType("Mirror.NetworkWriterPool");
		mirrorNwExtType = assembly.GetType("Mirror.NetworkWriterExtensions");
		mirrorNrExtType = assembly.GetType("Mirror.NetworkReaderExtensions");
		if (mirrorNbType == null || mirrorReaderType == null || mirrorConnType == null || mirrorRpcType == null || mirrorRcdType == null || mirrorRctType == null || mirrorRpcMsgType == null || mirrorNsType == null || mirrorNwpType == null || mirrorNwExtType == null || mirrorNrExtType == null)
		{
			return false;
		}
		mirrorRegisterDelegate = mirrorRpcType.GetMethod("RegisterDelegate", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		MethodInfo method = mirrorNsType.GetMethod("SendToAll", BindingFlags.Static | BindingFlags.Public);
		if (method != null)
		{
			mirrorNsSendToAll = method.MakeGenericMethod(mirrorRpcMsgType);
		}
		mirrorWriterExtWriteBool = mirrorNwExtType.GetMethod("WriteBool", BindingFlags.Static | BindingFlags.Public);
		mirrorWriterExtWriteULong = mirrorNwExtType.GetMethod("WriteULong", BindingFlags.Static | BindingFlags.Public);
		mirrorWriterPoolGet = mirrorNwpType.GetMethod("Get", BindingFlags.Static | BindingFlags.Public);
		mirrorWriterPoolReturn = mirrorNwpType.GetMethod("Return", BindingFlags.Static | BindingFlags.Public);
		Type type = assembly.GetType("Mirror.NetworkWriter");
		if (type != null)
		{
			mirrorWriterToArraySegment = type.GetMethod("ToArraySegment", BindingFlags.Instance | BindingFlags.Public);
		}
		mirrorReaderExtReadBool = mirrorNrExtType.GetMethod("ReadBool", BindingFlags.Static | BindingFlags.Public);
		mirrorReaderExtReadULong = mirrorNrExtType.GetMethod("ReadULong", BindingFlags.Static | BindingFlags.Public);
		mirrorNbNetId = mirrorNbType.GetProperty("netId", BindingFlags.Instance | BindingFlags.Public);
		mirrorNbComponentIndex = mirrorNbType.GetProperty("ComponentIndex", BindingFlags.Instance | BindingFlags.Public);
		mirrorRpcNetId = mirrorRpcMsgType.GetField("netId");
		mirrorRpcComponentIndex = mirrorRpcMsgType.GetField("componentIndex");
		mirrorRpcFunctionHash = mirrorRpcMsgType.GetField("functionHash");
		mirrorRpcPayload = mirrorRpcMsgType.GetField("payload");
		Type type2 = assembly2.GetType("PlayerInventory");
		Type type3 = assembly2.GetType("GameManager");
		if (type3 != null)
		{
			cachedLocalPlayerInventoryProperty = type3.GetProperty("LocalPlayerInventory", BindingFlags.Static | BindingFlags.Public);
		}
		if (mirrorRegisterDelegate != null && mirrorNsSendToAll != null && mirrorWriterExtWriteBool != null && mirrorWriterExtWriteULong != null && mirrorWriterPoolGet != null && mirrorWriterToArraySegment != null && mirrorReaderExtReadBool != null && mirrorReaderExtReadULong != null && mirrorNbNetId != null && mirrorNbComponentIndex != null && mirrorRpcNetId != null)
		{
			return type2 != null;
		}
		return false;
	}

	private static void RegisterRpcHandler()
	{
		if (mirrorRegisterDelegate == null || mirrorRcdType == null || mirrorNbType == null || mirrorReaderType == null || mirrorConnType == null || mirrorRctType == null)
		{
			return;
		}
		Type type = null;
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		for (int i = 0; i < assemblies.Length; i++)
		{
			type = assemblies[i].GetType("PlayerInventory");
			if (type != null)
			{
				break;
			}
		}
		if (type == null)
		{
			BirdieLog.Warning("[Birdie] Host bridge: PlayerInventory type not found.");
			return;
		}
		DynamicMethod dynamicMethod = new DynamicMethod("BirdieHostConfigRpcHandler", typeof(void), new Type[3] { mirrorNbType, mirrorReaderType, mirrorConnType }, typeof(BirdieHostBridge).Module, skipVisibility: true);
		MethodInfo method = typeof(BirdieHostBridge).GetMethod("ClientHandleSyncHostConfig", BindingFlags.Static | BindingFlags.NonPublic);
		if (method == null)
		{
			BirdieLog.Warning("[Birdie] Host bridge: ClientHandleSyncHostConfig not found via reflection.");
			return;
		}
		ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
		iLGenerator.Emit(OpCodes.Ldarg_0);
		iLGenerator.Emit(OpCodes.Ldarg_1);
		iLGenerator.Emit(OpCodes.Ldarg_2);
		iLGenerator.Emit(OpCodes.Call, method);
		iLGenerator.Emit(OpCodes.Ret);
		Delegate @delegate = dynamicMethod.CreateDelegate(mirrorRcdType);
		object obj = Enum.Parse(mirrorRctType, "ClientRpc");
		registeredRpcHash = (ushort)mirrorRegisterDelegate.Invoke(null, new object[5] { type, "System.Void PlayerInventory::BirdieCmdSyncHostConfig(System.Boolean,System.UInt64)", obj, @delegate, false });
		if (registeredRpcHash == 0)
		{
			BirdieLog.Warning("[Birdie] Host bridge: RegisterDelegate returned hash 0 — may indicate a collision.");
		}
	}
}
[BepInPlugin("com.cb12438.birdiemod", "Birdie Mod", "1.3.3")]
public class BirdieMod : BaseUnityPlugin
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static UnityAction <>9__633_2;

		internal void <BuildCreditsTab>b__633_2()
		{
			Application.OpenURL("https://discord.gg/EaCRS6TBH9");
		}
	}

	private ManualLogSource Logger;

	private readonly string[] cosmeticUnlockFlagNames = new string[3] { "everythingUnlocked", "forceUnlocked", "isCursorForceUnlocked" };

	private readonly string[] cosmeticRefreshMethodNames = new string[6] { "LoadCosmetics", "SaveCosmetics", "ListCosmeticsUnlocks", "RefreshOptions", "UpdateCosmeticsButtons", "UpdateLoadoutToggles" };

	private Component playerMovement;

	private Component playerGolfer;

	private Component golfBall;

	private readonly Dictionary<string, PropertyInfo> playerGolferProperties = new Dictionary<string, PropertyInfo>(8);

	private readonly Dictionary<string, FieldInfo> playerGolferFields = new Dictionary<string, FieldInfo>(4);

	private MethodInfo addSpeedBoostMethod;

	private FieldInfo swingNormalizedPowerBackingField;

	private bool playerFound;

	private bool assistEnabled;

	private bool isLeftMousePressed;

	private bool isRightMousePressed;

	private bool autoReleaseTriggeredThisCharge;

	private bool autoChargeSequenceStarted;

	private int lastAutoSwingReleaseFrame = -1;

	private float nextTryStartChargingTime;

	private readonly float tryStartChargingInterval = 0.05f;

	private float idealSwingPower;

	private float idealSwingPitch;

	private Vector3 flagPosition = Vector3.zero;

	private Vector3 holePosition = Vector3.zero;

	private Vector3 currentAimTargetPosition = Vector3.zero;

	private Vector3 currentSwingOriginPosition = Vector3.zero;

	private Vector3 aimTargetOffsetLocal = Vector3.zero;

	private readonly Vector3 swingOriginLocalOffset = new Vector3(0.86f, 0.05f, -0.12f);

	private string cachedLocalPlayerDisplayName = "";

	private float nextDisplayNameRefreshTime;

	private readonly float displayNameRefreshInterval = 0.5f;

	private int cachedAllGameObjectsFrame = -1;

	private GameObject[] cachedAllGameObjects;

	private int cachedAllComponentsFrame = -1;

	private Component[] cachedAllComponents;

	private float nextPlayerSearchTime;

	private float nextHoleSearchTime;

	private float nextIdealSwingCalculationTime;

	private float nextBallResolveTime;

	private readonly float playerSearchInterval = 1f;

	private readonly float holeSearchInterval = 0.5f;

	private readonly float idealSwingCalculationInterval = 0.25f;

	private readonly float ballResolveInterval = 0.2f;

	private readonly float puttDistanceThreshold = 12f;

	private bool hadResolvedPlayerContext;

	private bool hadResolvedBallContext;

	private string lastBallResolveSource = "missing";

	private Component initializedPlayerGolfer;

	private GameObject hudCanvas;

	private TextMeshProUGUI leftHudText;

	private TextMeshProUGUI centerHudText;

	private TextMeshProUGUI rightHudText;

	private TextMeshProUGUI bottomHudText;

	private bool isAimModeActive;

	private bool wasAimRequestedLastFrame;

	private bool reflectionCacheInitialized;

	private MethodInfo cachedTryGetMethod;

	private MethodInfo cachedOrbitSetYawMethod;

	private MethodInfo cachedOrbitSetPitchMethod;

	private MethodInfo cachedOrbitForceUpdateMethod;

	private MethodInfo cachedEnterSwingAimCameraMethod;

	private MethodInfo cachedExitSwingAimCameraMethod;

	private MethodInfo cachedReachOrbitSteadyStateMethod;

	private Component initializedYawPlayerMovement;

	private PropertyInfo cachedPlayerMovementYawProperty;

	private FieldInfo cachedPlayerMovementYawField;

	private Component initializedYawPlayerGolfer;

	private PropertyInfo cachedPlayerGolferYawProperty;

	private FieldInfo cachedPlayerGolferYawField;

	private bool cameraAimSmoothingInitialized;

	private float smoothedOrbitYaw;

	private float smoothedOrbitPitch;

	private float orbitYawVelocity;

	private float orbitPitchVelocity;

	private readonly float orbitAimSmoothTime = 0.02f;

	private readonly float orbitAimMaxSpeed = 2160f;

	private readonly object[] cachedOrbitModuleQueryArgs = new object[1];

	private readonly object[] cachedOrbitYawArgs = new object[1];

	private readonly object[] cachedOrbitPitchArgs = new object[1];

	private bool swingMathReflectionInitialized;

	private PropertyInfo cachedGolfSettingsProperty;

	private object cachedGolfSettingsObject;

	private PropertyInfo cachedGolfBallSettingsProperty;

	private object cachedGolfBallSettingsObject;

	private MethodInfo cachedBMathEaseInMethod;

	private MethodInfo cachedUpdateSwingNormalizedPowerMethod;

	private bool matchSetupRulesReflectionInitialized;

	private Type cachedMatchSetupRuleEnumType;

	private MethodInfo cachedMatchSetupGetValueMethod;

	private object cachedMatchSetupSwingPowerRuleValue;

	private PropertyInfo cachedLocalPlayerAsGolferProperty;

	private bool localGolferResolverInitialized;

	private MethodInfo cachedTryStartChargingSwingMethod;

	private MethodInfo cachedSetIsChargingSwingMethod;

	private MethodInfo cachedReleaseSwingChargeMethod;

	private float lastObservedSwingPower;

	private readonly float[] launchModelPowers = new float[4] { 0.1f, 0.5f, 1f, 1.15f };

	private readonly float[] launchModelSpeeds = new float[4] { 17f, 85f, 170f, 195.5f };

	private readonly float launchModelReferenceSrvMul = 2f;

	private bool golfBallVelocityReflectionInitialized;

	private Type cachedGolfBallTypeForVelocity;

	private PropertyInfo cachedGolfBallRigidbodyProperty;

	private bool rigidbodyVelocityReflectionInitialized;

	private PropertyInfo cachedRigidbodyLinearVelocityProperty;

	private readonly float trajectoryGravity = 9.81f;

	private bool windReflectionInitialized;

	private PropertyInfo cachedWindManagerWindProperty;

	private float windFactor = 1f;

	private float crossWindFactor = 1f;

	private bool swingHittableReflectionInitialized;

	private Component cachedGolfBallForHittable;

	private float cachedMaxPowerSwingHitSpeed = 85f;

	private float cachedMaxPowerPuttHitSpeed = 15f;

	private Vector3 windAimOffset = Vector3.zero;

	private GameObject shotPathObject;

	private LineRenderer shotPathLine;

	private Material shotPathMaterial;

	private GameObject predictedPathObject;

	private LineRenderer predictedPathLine;

	private Material predictedPathMaterial;

	private GameObject frozenPredictedPathObject;

	private LineRenderer frozenPredictedPathLine;

	private Material frozenPredictedPathMaterial;

	private readonly List<Vector3> shotPathPoints = new List<Vector3>(768);

	private readonly List<Vector3> predictedPathPoints = new List<Vector3>(384);

	private readonly List<Vector3> frozenPredictedPathPoints = new List<Vector3>(384);

	private bool predictedImpactPreviewValid;

	private Vector3 predictedImpactPreviewPoint = Vector3.zero;

	private Vector3 predictedImpactPreviewApproachDirection = Vector3.forward;

	private bool frozenImpactPreviewValid;

	private Vector3 frozenImpactPreviewPoint = Vector3.zero;

	private Vector3 frozenImpactPreviewApproachDirection = Vector3.forward;

	private bool lockLivePredictedPath;

	private bool observedBallMotionSinceLastShot;

	private bool isRecordingShotPath;

	private float predictedTrajectoryHideStartTime;

	private float nextPredictedPathRefreshTime;

	private Vector3 lastShotPathBallPosition = Vector3.zero;

	private float lastShotPathMoveTime;

	private readonly float predictedUnlockSpeedThreshold = 0.12f;

	private readonly float shotPathHeightOffset = 0.14f;

	private readonly float shotPathMoveThreshold = 0.004f;

	private readonly float shotPathPointSpacing = 0.012f;

	private readonly int shotPathMaxPoints = 3072;

	private readonly float shotPathStationaryDelay = 0.65f;

	private readonly int predictedPathMaxSteps = 360;

	private readonly float predictedPathMaxTime = 7.2f;

	private readonly float predictedPathPointSpacing = 0.3f;

	private readonly float predictedPathRefreshInterval = 0.05f;

	private readonly float predictedTrajectoryUnlockFallbackDelay = 0.75f;

	private bool predictedPathCacheValid;

	private Component cachedPredictedPathBall;

	private Vector3 cachedPredictedShotOrigin = Vector3.zero;

	private Vector3 cachedPredictedAimTargetPosition = Vector3.zero;

	private float cachedPredictedSwingPower;

	private float cachedPredictedSwingPitch;

	private readonly float predictedPathRebuildDistanceEpsilon = 0.015f;

	private readonly float predictedPathRebuildPowerEpsilon = 0.0025f;

	private readonly float predictedPathRebuildPitchEpsilon = 0.05f;

	private readonly string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Mods", "BirdieMod.cfg");

	private string assistToggleKeyName = "F";

	private string coffeeBoostKeyName = "F2";

	private string nearestBallModeKeyName = "F3";

	private string unlockAllCosmeticsKeyName = "F4";

	private string itemSpawnerKeyName = "F5";

	private string hudToggleKeyName = "H";

	private string randomItemKeyName = "G";

	private string assistToggleKeyLabel = "F";

	private string coffeeBoostKeyLabel = "F2";

	private string nearestBallModeKeyLabel = "F3";

	private string unlockAllCosmeticsKeyLabel = "F4";

	private string itemSpawnerKeyLabel = "F5";

	private string hudToggleKeyLabel = "H";

	private string randomItemKeyLabel = "G";

	private Key assistToggleKey = (Key)20;

	private Key coffeeBoostKey = (Key)95;

	private Key nearestBallModeKey = (Key)96;

	private Key unlockAllCosmeticsKey = (Key)97;

	private Key itemSpawnerKey = (Key)98;

	private Key hudToggleKey = (Key)22;

	private Key randomItemKey = (Key)21;

	private bool hudVisible = true;

	private bool itemMenuOpen;

	private GameObject itemMenuPanelObject;

	private TextMeshProUGUI itemMenuText;

	private bool actualTrailEnabled = true;

	private bool predictedTrailEnabled = true;

	private bool frozenTrailEnabled = true;

	private bool impactPreviewEnabled = true;

	private float impactPreviewTargetFps;

	private int impactPreviewTextureWidth = 640;

	private int impactPreviewTextureHeight = 360;

	private float actualTrailStartWidth = 0.22f;

	private float actualTrailEndWidth = 0.18f;

	private float predictedTrailStartWidth = 0.18f;

	private float predictedTrailEndWidth = 0.14f;

	private float frozenTrailStartWidth = 0.2f;

	private float frozenTrailEndWidth = 0.16f;

	private Color actualTrailColor = new Color(1f, 0.58f, 0.2f, 1f);

	private Color predictedTrailColor = new Color(0.36f, 0.95f, 0.46f, 0.95f);

	private Color frozenTrailColor = new Color(0.36f, 0.74f, 1f, 0.92f);

	private bool visualsInitialized;

	private readonly float visualsInitializationDelay = 2.5f;

	private bool trailVisualSettingsDirty = true;

	private bool actualTrailLineDirty = true;

	private bool predictedTrailLineDirty = true;

	private bool frozenTrailLineDirty = true;

	private bool hudDirty = true;

	private float nextHudRefreshTime;

	private readonly float hudRefreshInterval = 0.1f;

	private string cachedLeftHudText = "";

	private string cachedCenterHudText = "";

	private string cachedRightHudText = "";

	private string cachedBottomHudText = "";

	private bool nearestAnyBallModeEnabled;

	private float nextNearestAnyBallResolveTime;

	private readonly float nearestAnyBallResolveInterval = 0.1f;

	private readonly List<Component> cachedGolfBalls = new List<Component>(64);

	private float nextGolfBallCacheRefreshTime;

	private readonly float golfBallCacheRefreshInterval = 0.75f;

	private readonly float emptyGolfBallCacheRefreshInterval = 2f;

	private float nextImpactPreviewRenderTime;

	private Camera cachedImpactPreviewReferenceCamera;

	private float nextImpactPreviewReferenceCameraRefreshTime;

	private readonly float impactPreviewReferenceCameraRefreshInterval = 1f;

	private readonly float impactPreviewAutoTargetFps = 60f;

	private readonly RaycastHit[] impactPreviewRaycastHits = (RaycastHit[])(object)new RaycastHit[24];

	private readonly RaycastHit[] impactPreviewGroundProbeHits = (RaycastHit[])(object)new RaycastHit[24];

	private readonly object[] cachedSpeedBoostArgs = new object[1];

	private readonly object[] cachedEaseInArgs = new object[1];

	private readonly object[] cachedMatchSetupGetValueArgs = new object[1];

	private readonly object[] cachedChargingStateArgs = new object[1];

	private readonly object[] cachedUpdateSwingPowerArgs = new object[2] { true, false };

	private string iceToggleKeyName = "I";

	private string iceToggleKeyLabel = "I";

	private Key iceToggleKey = (Key)23;

	private bool iceImmunityEnabled;

	private bool iceReflectionInitialized;

	private FieldInfo cachedHorizontalDragField;

	private PropertyInfo cachedPlayerMovementSettingsProperty;

	private float normalHorizontalDragValue = 10f;

	private string settingsKeyName = "F6";

	private string settingsKeyLabel = "F6";

	private Key settingsKey = (Key)99;

	private bool settingsPanelOpen;

	private int settingsTabIndex;

	private bool keybindRebindMode;

	private int keybindRebindIndex = -1;

	private GameObject settingsPanelObject;

	private static Sprite s_roundedLg = null;

	private static Sprite s_roundedMd = null;

	private static Sprite s_roundedSm = null;

	private static Sprite s_pillSprite = null;

	private static Sprite s_circleSprite = null;

	private Button[] settingsV2NavButtons = (Button[])(object)new Button[5];

	private GameObject[] settingsV2TabPanels = (GameObject[])(object)new GameObject[5];

	private Button[] settingsKeybindRowButtons;

	private Image[] settingsHudTogglePillBgs;

	private TMP_InputField settingsCreditsInputField;

	private TextMeshProUGUI settingsKeybindRebindStatusLabel;

	private bool settingsInputReflectionInitialized;

	private MethodInfo cachedCursorSetForceUnlockedMethod;

	private MethodInfo cachedInputManagerEnableModeMethod;

	private MethodInfo cachedInputManagerDisableModeMethod;

	private object cachedInputModePausedValue;

	private int creditsGrantAmount = 1000;

	private bool creditsReflectionInitialized;

	private MethodInfo cachedRewardCreditsMethod;

	private bool hudShowBottomBar = true;

	private bool hudShowBallDistance = true;

	private bool hudShowIceIndicator = true;

	private bool hudShowCenterTitle = true;

	private bool hudShowPlayerInfo = true;

	private bool tracersEnabled = true;

	private string noWindKeyName = "F7";

	private string noWindKeyLabel = "F7";

	private Key noWindKey = (Key)100;

	private bool noWindEnabled;

	private bool windExtrasReflectionInitialized;

	private object cachedWindSettingsInstance;

	private FieldInfo cachedWindForceScaleField;

	private float savedWindForceScale = 1f;

	private string perfectShotKeyName = "F8";

	private string perfectShotKeyLabel = "F8";

	private Key perfectShotKey = (Key)101;

	private bool perfectShotEnabled;

	private string noAirDragKeyName = "F9";

	private string noAirDragKeyLabel = "F9";

	private Key noAirDragKey = (Key)102;

	private bool noAirDragEnabled;

	private bool airDragExtrasReflectionInitialized;

	private FieldInfo cachedLinearAirDragField;

	private float savedLinearAirDrag = 0.01f;

	private string speedMultiplierKeyName = "F10";

	private string speedMultiplierKeyLabel = "F10";

	private Key speedMultiplierKey = (Key)103;

	private bool speedMultiplierEnabled;

	private float speedMultiplierFactor = 2f;

	private bool moveSpeedExtrasReflectionInitialized;

	private PropertyInfo cachedPlayerMovSettingsProperty;

	private FieldInfo cachedDefaultMoveSpeedField;

	private float savedDefaultMoveSpeed = 7f;

	private string infiniteAmmoKeyName = "F11";

	private string infiniteAmmoKeyLabel = "F11";

	private Key infiniteAmmoKey = (Key)104;

	private bool infiniteAmmoEnabled;

	private bool ammoInventoryReflectionReady;

	private FieldInfo cachedInventorySlotsSyncListField;

	private FieldInfo cachedInventoryOverridesDictField;

	private FieldInfo cachedInvSlotItemTypeField;

	private ConstructorInfo cachedInvSlotConstructor;

	private readonly Dictionary<int, object> ammoItemTypeBackup = new Dictionary<int, object>();

	private string noRecoilKeyName = "F12";

	private string noRecoilKeyLabel = "F12";

	private Key noRecoilKey = (Key)105;

	private bool noRecoilEnabled;

	private bool screenshakeExtrasReflectionInitialized;

	private object cachedScreenshakeOwner;

	private FieldInfo cachedScreenshakeFactorField;

	private float savedScreenshakeFactor = 1f;

	private string noKnockbackKeyName = "N";

	private string noKnockbackKeyLabel = "N";

	private Key noKnockbackKey = (Key)28;

	private bool noKnockbackEnabled;

	private bool knockbackImmunityReflectionReady;

	private FieldInfo cachedKnockoutImmunityStatusField;

	private FieldInfo cachedHasImmunityField;

	private Component localPlayerHittable;

	private string landmineImmunityKeyName = "M";

	private string landmineImmunityKeyLabel = "M";

	private Key landmineImmunityKey = (Key)27;

	private bool landmineImmunityEnabled;

	private string lockOnAnyDistanceKeyName = "L";

	private string lockOnAnyDistanceKeyLabel = "L";

	private Key lockOnAnyDistanceKey = (Key)26;

	private bool lockOnAnyDistanceEnabled;

	private bool lockOnReflectionInitialized;

	private FieldInfo cachedLockOnMaxDistanceField;

	private float savedLockOnMaxDistance = 60f;

	private string expandedSlotsKeyName = "U";

	private string expandedSlotsKeyLabel = "U";

	private Key expandedSlotsKey = (Key)35;

	private bool expandedSlotsEnabled;

	private bool expandedSlotsAllPlayers = true;

	private const int ExpandedSlotsTarget = 7;

	private bool expandedSlotsReflectionInitialized;

	private object cachedExpandedHotkeysInstance;

	private FieldInfo cachedHotkeyUisField;

	private object cachedExpandedPlayerInvSettings;

	private FieldInfo cachedMaxItemsBackingField;

	private int savedOriginalMaxItems = 3;

	private Array savedOriginalHotkeyUisArray;

	private List<GameObject> spawnedExtraHotkeyUiObjects = new List<GameObject>();

	private Vector2 savedSlotParentSizeDelta;

	private bool savedSlotParentMaskEnabled;

	private Transform savedSlotParentTransform;

	private bool hostControlsActive;

	private ulong hostAllowedFeatureMask = 65535uL;

	private byte _hostSelectedWeather;

	private bool _hostWeatherRunning;

	private static bool _perfectShotLogged;

	private GameObject impactPreviewPanelObject;

	private RawImage impactPreviewRawImage;

	private RenderTexture impactPreviewTexture;

	private GameObject impactPreviewCameraObject;

	private Camera impactPreviewCamera;

	private readonly float impactPreviewLookHeightOffset = 0.65f;

	private readonly float impactPreviewProbeHeight = 36f;

	private readonly float impactPreviewCameraMinDistance = 9.5f;

	private readonly float impactPreviewCameraMaxDistance = 20f;

	private readonly float impactPreviewCameraMinHeight = 6.2f;

	private readonly float impactPreviewCameraMaxHeight = 12.5f;

	private readonly float impactPreviewFieldOfView = 52f;

	private readonly float impactPreviewOrbitDegreesPerSecond = 26f;

	private readonly float impactPreviewGroundClearance = 1.85f;

	private readonly float impactPreviewMinVerticalLookOffset = 2.25f;

	private const int CoffeeItemTypeInt = 1;

	private static readonly int[] SpawnableItemTypeInts = new int[12]
	{
		1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
		11, 12
	};

	private static readonly string[] SpawnableItemNames = new string[12]
	{
		"Coffee", "Dueling Pistol", "Elephant Gun", "Airhorn", "Spring Boots", "Golf Cart", "Rocket Launcher", "Landmine", "Electromagnet", "Orbital Laser",
		"Rocket Driver", "Freeze Bomb"
	};

	private static readonly Key[] SpawnableItemKeys;

	private static readonly string[] SpawnableItemKeyLabels;

	private bool itemSpawnerReflectionInitialized;

	private bool dispenserReflectionInitialized;

	private Type cachedItemDispenserType;

	private FieldInfo cachedItemDispenserItemTypeField;

	private PropertyInfo cachedItemDispenserIsEnabledProperty;

	private MethodInfo cachedItemDispenserCmdDispenseMethod;

	private Type cachedPhysicalItemType;

	private FieldInfo cachedPhysicalItemItemTypeField;

	private MethodInfo cachedCmdGiveToPlayerMethod;

	private bool dispenserPickupPending;

	private int dispenserPickupItemTypeInt;

	private Component dispenserPickupLocalInventory;

	private float dispenserPickupDeadline;

	private const float dispenserPickupTimeout = 2.5f;

	private bool crateReflectionInitialized;

	private bool pendingCrateTeleport;

	private float pendingCrateTeleportExpiry;

	private const float crateTeleportConfirmWindow = 3f;

	private bool crateReturnPending;

	private Vector3 crateReturnPosition;

	private Type cachedItemSpawnerType;

	private FieldInfo cachedItemSpawnerSettingsField;

	private PropertyInfo cachedItemSpawnerNetHasItemBoxProp;

	private Type cachedItemSpawnerSettingsType;

	private MethodInfo cachedGetRandomItemForMethod;

	private PropertyInfo cachedInventoryPlayerInfoProp;

	private PropertyInfo cachedNetworkServerActiveProperty;

	private bool cachedNetworkServerPropertyInit;

	private PropertyInfo cachedLocalPlayerInventoryProperty;

	private PropertyInfo cachedAllItemsProperty;

	private MethodInfo cachedTryGetItemDataMethod;

	private PropertyInfo cachedItemDataMaxUsesProperty;

	private Type cachedItemTypeEnumType;

	private MethodInfo cachedServerTryAddItemMethod;

	private Rect _imRect;

	private bool _imRectInit;

	private Vector2 _imFeaturesScroll;

	private Vector2 _imKeysScroll;

	private bool _imStylesReady;

	private GUIStyle _imWindowStyle;

	private GUIStyle _imTitleStyle;

	private GUIStyle _imTabActive;

	private GUIStyle _imTabIdle;

	private GUIStyle _imSectionLabel;

	private GUIStyle _imToggleOn;

	private GUIStyle _imToggleOff;

	private GUIStyle _imActionLabel;

	private GUIStyle _imKeyBadge;

	private GUIStyle _imRebindActive;

	private GUIStyle _imButton;

	private GUIStyle _imCloseBtn;

	private GUIStyle _imInfoLabel;

	private GUIStyle _imDescLabel;

	private Texture2D _imTxDark;

	private Texture2D _imTxBlue;

	private Texture2D _imTxGrey;

	private Texture2D _imTxDarker;

	private Texture2D _imTxRed;

	private Texture2D _imTxGreen;

	private Texture2D _imTxSeparator;

	private Vector2 _imItemsScroll;

	private Vector2 _imNetScroll;

	private static readonly string[] SettingsKeybindDisplayNames;

	private static readonly Key[] SettingsSelectionKeys;

	private byte _currentWeatherType;

	private bool _weatherPhysicsApplied;

	private float _originalLinearAirDrag;

	private bool _originalAirDragCached;

	private float _originalWindForceScale;

	private bool _originalWindForceScaleCached;

	private float _nextLightningTime;

	private float _nextGustTime;

	private float _tornadoMoveTimer;

	private Vector3 _tornadoWorldPosition;

	private bool _tornadoPositionSet;

	private float _lightningFlashEndTime;

	private bool _lightningStrikePending;

	private Vector3 _pendingLightningStrikePosition;

	internal bool autoWeatherEnabled;

	internal int autoWeatherChance = 40;

	internal int[] autoWeatherChances = new int[8] { 50, 35, 20, 40, 25, 10, 15, 5 };

	private bool _holeEventSubscribed;

	private float _tornadoFlingNextTime;

	private bool _wAirDragReady;

	private FieldInfo _wAirDragField;

	private object _wBallSettings;

	private bool _wWindReady;

	private object _wWindSettings;

	private FieldInfo _wWindScaleField;

	private bool _wWmReady;

	private Type _wWmType;

	private PropertyInfo _wWmSpeedProp;

	private PropertyInfo _wWmAngleProp;

	private bool _gustRunning;

	private bool _lightningRunning;

	private float _currentRainDragMul = 1f;

	private float _nextWindDragUpdateTime;

	private float _nextErraticWindShiftTime;

	private object _cachedWmObject;

	private float _nextWmCacheRefreshTime;

	private readonly List<Material> _weatherMaterials = new List<Material>();

	private GameObject _weatherVfxRoot;

	private ParticleSystem _rainPs;

	private ParticleSystem _tornadoPs;

	private Light _lightningLight;

	private AudioSource _weatherAudio;

	private bool _lightningScreenFlash;

	private float _lightningScreenFlashEnd;

	private bool _playerStruckFlash;

	private float _playerStruckFlashEnd;

	private AudioSource _weatherAudio2;

	private AudioClip _clipRainLoop;

	private AudioClip _clipWindLoop;

	private AudioClip _clipWindGust;

	private AudioClip _clipThunderCrack;

	private AudioClip _clipTornadoLoop;

	private bool _soundsLoaded;

	private void Awake()
	{
		Logger = ((BaseUnityPlugin)this).Logger;
		BirdieLog.MsgImpl = delegate(string s)
		{
			Logger.LogInfo((object)s);
		};
		BirdieLog.WarnImpl = delegate(string s)
		{
			Logger.LogWarning((object)s);
		};
		BirdieCoroutine.StartImpl = delegate(IEnumerator e)
		{
			((MonoBehaviour)this).StartCoroutine(e);
		};
		BirdieInit();
	}

	private void Update()
	{
		BirdieUpdate();
	}

	private void LateUpdate()
	{
		BirdieLateUpdate();
	}

	private void OnGUI()
	{
		BirdieOnGUI();
	}

	private void InitializeReflectionCache()
	{
		if (reflectionCacheInitialized)
		{
			return;
		}
		try
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (cachedTryGetMethod == null)
				{
					Type type = assembly.GetType("CameraModuleController");
					if (type != null)
					{
						cachedTryGetMethod = type.GetMethod("TryGetOrbitModule", BindingFlags.Static | BindingFlags.Public);
					}
				}
				if (cachedEnterSwingAimCameraMethod == null)
				{
					Type type2 = assembly.GetType("GameplayCameraManager");
					if (type2 != null)
					{
						cachedEnterSwingAimCameraMethod = type2.GetMethod("EnterSwingAimCamera", BindingFlags.Static | BindingFlags.Public);
						cachedExitSwingAimCameraMethod = type2.GetMethod("ExitSwingAimCamera", BindingFlags.Static | BindingFlags.Public);
						cachedReachOrbitSteadyStateMethod = type2.GetMethod("ReachOrbitCameraSteadyState", BindingFlags.Static | BindingFlags.Public);
					}
				}
				if (cachedTryGetMethod != null && cachedEnterSwingAimCameraMethod != null)
				{
					break;
				}
			}
			object obj = TryGetOrbitModule();
			if (obj != null)
			{
				Type type3 = obj.GetType();
				cachedOrbitSetYawMethod = type3.GetMethod("SetYaw", BindingFlags.Instance | BindingFlags.Public);
				cachedOrbitSetPitchMethod = type3.GetMethod("SetPitch", BindingFlags.Instance | BindingFlags.Public);
				cachedOrbitForceUpdateMethod = type3.GetMethod("ForceUpdateModule", BindingFlags.Instance | BindingFlags.Public);
			}
		}
		catch
		{
		}
		reflectionCacheInitialized = true;
	}

	private object TryGetOrbitModule()
	{
		if (cachedTryGetMethod == null)
		{
			return null;
		}
		try
		{
			cachedOrbitModuleQueryArgs[0] = null;
			return ((bool)cachedTryGetMethod.Invoke(null, cachedOrbitModuleQueryArgs)) ? cachedOrbitModuleQueryArgs[0] : null;
		}
		catch
		{
			return null;
		}
	}

	private FieldInfo FindYawField(Type componentType)
	{
		FieldInfo field = componentType.GetField("targetYaw", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (!(field != null) || !(field.FieldType == typeof(float)))
		{
			return null;
		}
		return field;
	}

	private void CacheYawAccessorsForComponent(Component component, ref Component initializedComponent, ref PropertyInfo yawProperty, ref FieldInfo yawField)
	{
		if ((Object)(object)component == (Object)null)
		{
			initializedComponent = null;
			yawProperty = null;
			yawField = null;
		}
		else if (initializedComponent != component)
		{
			initializedComponent = component;
			Type type = ((object)component).GetType();
			yawProperty = type.GetProperty("Yaw", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			yawField = FindYawField(type);
		}
	}

	private void EnsureAimYawAccessors()
	{
		CacheYawAccessorsForComponent(playerMovement, ref initializedYawPlayerMovement, ref cachedPlayerMovementYawProperty, ref cachedPlayerMovementYawField);
		CacheYawAccessorsForComponent(playerGolfer, ref initializedYawPlayerGolfer, ref cachedPlayerGolferYawProperty, ref cachedPlayerGolferYawField);
	}

	private void ApplyYawToAimComponent(Component component, PropertyInfo yawProperty, FieldInfo yawField, float targetYaw)
	{
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		try
		{
			if (yawProperty != null && yawProperty.CanWrite && yawProperty.PropertyType == typeof(float))
			{
				yawProperty.SetValue(component, targetYaw, null);
			}
		}
		catch
		{
		}
		try
		{
			if (yawField != null && yawField.FieldType == typeof(float))
			{
				yawField.SetValue(component, targetYaw);
			}
		}
		catch
		{
		}
		try
		{
			component.transform.rotation = Quaternion.Euler(0f, targetYaw, 0f);
		}
		catch
		{
		}
	}

	private void ApplyAimDirectionToSwingSubject(float targetYaw)
	{
		EnsureAimYawAccessors();
		ApplyYawToAimComponent(playerMovement, cachedPlayerMovementYawProperty, cachedPlayerMovementYawField, targetYaw);
		if (playerGolfer != playerMovement)
		{
			ApplyYawToAimComponent(playerGolfer, cachedPlayerGolferYawProperty, cachedPlayerGolferYawField, targetYaw);
		}
	}

	private void SetSwingAimCameraState(bool enabled)
	{
		if (enabled == wasAimRequestedLastFrame)
		{
			return;
		}
		wasAimRequestedLastFrame = enabled;
		MethodInfo methodInfo = (enabled ? cachedEnterSwingAimCameraMethod : cachedExitSwingAimCameraMethod);
		if (methodInfo == null)
		{
			return;
		}
		try
		{
			methodInfo.Invoke(null, null);
			if (enabled && cachedReachOrbitSteadyStateMethod != null)
			{
				cachedReachOrbitSteadyStateMethod.Invoke(null, null);
			}
		}
		catch
		{
		}
	}

	private void DisableAutoAimCamera()
	{
		isAimModeActive = false;
		cameraAimSmoothingInitialized = false;
		orbitYawVelocity = 0f;
		orbitPitchVelocity = 0f;
		SetSwingAimCameraState(enabled: false);
	}

	private bool IsPlayerAimingSwing()
	{
		if ((Object)(object)playerGolfer == (Object)null)
		{
			return false;
		}
		if (!playerGolferProperties.TryGetValue("IsAimingSwing", out var value) || value == null)
		{
			return false;
		}
		try
		{
			return Convert.ToBoolean(value.GetValue(playerGolfer, null));
		}
		catch
		{
			return false;
		}
	}

	private void AutoAimCamera()
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		if (!assistEnabled || (!isLeftMousePressed && !isRightMousePressed) || !IsPlayerAimingSwing() || (Object)(object)playerGolfer == (Object)null || holePosition == Vector3.zero)
		{
			DisableAutoAimCamera();
			return;
		}
		try
		{
			InitializeReflectionCache();
			object obj = TryGetOrbitModule();
			if (obj == null || cachedOrbitSetYawMethod == null || cachedOrbitSetPitchMethod == null)
			{
				DisableAutoAimCamera();
				return;
			}
			SetSwingAimCameraState(enabled: true);
			Vector3 position = playerGolfer.transform.position;
			Vector3 playerPosition = (((Object)(object)golfBall != (Object)null) ? golfBall.transform.position : position);
			currentAimTargetPosition = GetAimTargetPosition(playerPosition) + windAimOffset;
			currentSwingOriginPosition = GetSwingOriginPosition();
			if (currentAimTargetPosition == Vector3.zero || currentSwingOriginPosition == Vector3.zero)
			{
				DisableAutoAimCamera();
				return;
			}
			Vector3 val = currentAimTargetPosition - currentSwingOriginPosition;
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				DisableAutoAimCamera();
				return;
			}
			float num = Mathf.Atan2(val.x, val.z) * 57.29578f;
			float magnitude = ((Vector3)(ref val)).magnitude;
			float num2 = Mathf.Clamp(magnitude * 0.9f, 4f, 15f);
			float num3 = Mathf.Lerp(3.25f, 8f, Mathf.InverseLerp(0f, 25f, magnitude));
			Vector3 val2 = position - ((Vector3)(ref val)).normalized * num2;
			val2.y += num3;
			Vector3 val3 = currentAimTargetPosition - val2;
			float num4 = (0f - Mathf.Asin(Mathf.Clamp(((Vector3)(ref val3)).normalized.y, -0.999f, 0.999f))) * 57.29578f;
			if (!cameraAimSmoothingInitialized || !isAimModeActive)
			{
				smoothedOrbitYaw = num;
				smoothedOrbitPitch = num4;
				orbitYawVelocity = 0f;
				orbitPitchVelocity = 0f;
				cameraAimSmoothingInitialized = true;
			}
			else
			{
				float num5 = Mathf.Max(0.0001f, Time.deltaTime);
				smoothedOrbitYaw = Mathf.SmoothDampAngle(smoothedOrbitYaw, num, ref orbitYawVelocity, orbitAimSmoothTime, orbitAimMaxSpeed, num5);
				smoothedOrbitPitch = Mathf.SmoothDampAngle(smoothedOrbitPitch, num4, ref orbitPitchVelocity, orbitAimSmoothTime, orbitAimMaxSpeed, num5);
			}
			ApplyAimDirectionToSwingSubject(smoothedOrbitYaw);
			cachedOrbitYawArgs[0] = smoothedOrbitYaw;
			cachedOrbitPitchArgs[0] = smoothedOrbitPitch;
			cachedOrbitSetYawMethod.Invoke(obj, cachedOrbitYawArgs);
			cachedOrbitSetPitchMethod.Invoke(obj, cachedOrbitPitchArgs);
			if (cachedOrbitForceUpdateMethod != null)
			{
				cachedOrbitForceUpdateMethod.Invoke(obj, null);
			}
			isAimModeActive = true;
		}
		catch
		{
			DisableAutoAimCamera();
		}
	}

	private void LoadOrCreateConfig()
	{
		ApplyDefaultConfig();
		try
		{
			string directoryName = Path.GetDirectoryName(configPath);
			if (!string.IsNullOrEmpty(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			if (!File.Exists(configPath))
			{
				File.WriteAllText(configPath, BuildDefaultConfigText(), Encoding.ASCII);
			}
			else
			{
				LoadConfigFromFile(configPath);
			}
		}
		catch
		{
		}
		UpdateConfigLabels();
		MarkHudDirty();
		MarkTrailVisualSettingsDirty();
		nextImpactPreviewRenderTime = 0f;
	}

	private void ApplyDefaultConfig()
	{
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		assistToggleKeyName = "F1";
		coffeeBoostKeyName = "F2";
		nearestBallModeKeyName = "F3";
		unlockAllCosmeticsKeyName = "F4";
		itemSpawnerKeyName = "F5";
		hudToggleKeyName = "H";
		randomItemKeyName = "G";
		iceToggleKeyName = "I";
		settingsKeyName = "F6";
		noWindKeyName = "W";
		perfectShotKeyName = "P";
		noAirDragKeyName = "D";
		speedMultiplierKeyName = "S";
		speedMultiplierFactor = 2f;
		infiniteAmmoKeyName = "A";
		noRecoilKeyName = "R";
		noKnockbackKeyName = "K";
		landmineImmunityKeyName = "M";
		lockOnAnyDistanceKeyName = "L";
		expandedSlotsKeyName = "U";
		hudShowBottomBar = true;
		hudShowBallDistance = true;
		hudShowIceIndicator = true;
		hudShowCenterTitle = true;
		hudShowPlayerInfo = true;
		tracersEnabled = true;
		creditsGrantAmount = 1000;
		actualTrailEnabled = true;
		predictedTrailEnabled = true;
		frozenTrailEnabled = true;
		impactPreviewEnabled = true;
		impactPreviewTargetFps = impactPreviewAutoTargetFps;
		impactPreviewTextureWidth = 640;
		impactPreviewTextureHeight = 360;
		actualTrailStartWidth = 0.22f;
		actualTrailEndWidth = 0.18f;
		predictedTrailStartWidth = 0.18f;
		predictedTrailEndWidth = 0.14f;
		frozenTrailStartWidth = 0.2f;
		frozenTrailEndWidth = 0.16f;
		actualTrailColor = new Color(1f, 0.58f, 0.2f, 1f);
		predictedTrailColor = new Color(0.36f, 0.95f, 0.46f, 0.95f);
		frozenTrailColor = new Color(0.36f, 0.74f, 1f, 0.92f);
		hostAllowedFeatureMask = 16383uL;
	}

	private void LoadConfigFromFile(string path)
	{
		//IL_0bee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bf3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bf8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bc2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bc7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bcc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bd8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bdd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0be2: Unknown result type (might be due to invalid IL or missing references)
		string[] array = File.ReadAllLines(path);
		foreach (string text in array)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				continue;
			}
			string text2 = text.Trim();
			if (text2.StartsWith("#", StringComparison.Ordinal) || text2.StartsWith(";", StringComparison.Ordinal))
			{
				continue;
			}
			int num = text2.IndexOf('=');
			if (num <= 0)
			{
				continue;
			}
			string text3 = text2.Substring(0, num).Trim().ToLowerInvariant();
			string text4 = text2.Substring(num + 1).Trim();
			switch (text3)
			{
			case "assist_toggle_key":
				assistToggleKeyName = ParseKeyNameOrDefault(text4, assistToggleKeyName);
				break;
			case "coffee_boost_key":
				coffeeBoostKeyName = ParseKeyNameOrDefault(text4, coffeeBoostKeyName);
				break;
			case "nearest_ball_mode_key":
				nearestBallModeKeyName = ParseKeyNameOrDefault(text4, nearestBallModeKeyName);
				break;
			case "unlock_all_cosmetics_key":
				unlockAllCosmeticsKeyName = ParseKeyNameOrDefault(text4, unlockAllCosmeticsKeyName);
				break;
			case "item_spawner_key":
				itemSpawnerKeyName = ParseKeyNameOrDefault(text4, itemSpawnerKeyName);
				break;
			case "hud_toggle_key":
				hudToggleKeyName = ParseKeyNameOrDefault(text4, hudToggleKeyName);
				break;
			case "random_item_key":
				randomItemKeyName = ParseKeyNameOrDefault(text4, randomItemKeyName);
				break;
			case "ice_toggle_key":
				iceToggleKeyName = ParseKeyNameOrDefault(text4, iceToggleKeyName);
				break;
			case "settings_key":
				settingsKeyName = ParseKeyNameOrDefault(text4, settingsKeyName);
				break;
			case "no_wind_key":
				noWindKeyName = ParseKeyNameOrDefault(text4, noWindKeyName);
				break;
			case "perfect_shot_key":
				perfectShotKeyName = ParseKeyNameOrDefault(text4, perfectShotKeyName);
				break;
			case "no_air_drag_key":
				noAirDragKeyName = ParseKeyNameOrDefault(text4, noAirDragKeyName);
				break;
			case "speed_multiplier_key":
				speedMultiplierKeyName = ParseKeyNameOrDefault(text4, speedMultiplierKeyName);
				break;
			case "speed_multiplier_factor":
				speedMultiplierFactor = ParseFloatOrDefault(text4, speedMultiplierFactor, 0.1f, 20f);
				break;
			case "infinite_ammo_key":
				infiniteAmmoKeyName = ParseKeyNameOrDefault(text4, infiniteAmmoKeyName);
				break;
			case "no_recoil_key":
				noRecoilKeyName = ParseKeyNameOrDefault(text4, noRecoilKeyName);
				break;
			case "no_knockback_key":
				noKnockbackKeyName = ParseKeyNameOrDefault(text4, noKnockbackKeyName);
				break;
			case "landmine_immunity_key":
				landmineImmunityKeyName = ParseKeyNameOrDefault(text4, landmineImmunityKeyName);
				break;
			case "lock_on_any_distance_key":
				lockOnAnyDistanceKeyName = ParseKeyNameOrDefault(text4, lockOnAnyDistanceKeyName);
				break;
			case "expanded_slots_key":
				expandedSlotsKeyName = ParseKeyNameOrDefault(text4, expandedSlotsKeyName);
				break;
			case "expanded_slots_all_players":
				expandedSlotsAllPlayers = ParseBoolOrDefault(text4, expandedSlotsAllPlayers);
				break;
			case "hud_show_bottom_bar":
				hudShowBottomBar = ParseBoolOrDefault(text4, hudShowBottomBar);
				break;
			case "hud_show_ball_distance":
				hudShowBallDistance = ParseBoolOrDefault(text4, hudShowBallDistance);
				break;
			case "hud_show_ice_indicator":
				hudShowIceIndicator = ParseBoolOrDefault(text4, hudShowIceIndicator);
				break;
			case "hud_show_center_title":
				hudShowCenterTitle = ParseBoolOrDefault(text4, hudShowCenterTitle);
				break;
			case "hud_show_player_info":
				hudShowPlayerInfo = ParseBoolOrDefault(text4, hudShowPlayerInfo);
				break;
			case "tracers_enabled":
				tracersEnabled = ParseBoolOrDefault(text4, tracersEnabled);
				break;
			case "credits_grant_amount":
				creditsGrantAmount = ParseIntOrDefault(text4, creditsGrantAmount, 0, 999999);
				break;
			case "actual_trail_enabled":
				actualTrailEnabled = ParseBoolOrDefault(text4, actualTrailEnabled);
				break;
			case "predicted_trail_enabled":
				predictedTrailEnabled = ParseBoolOrDefault(text4, predictedTrailEnabled);
				break;
			case "frozen_trail_enabled":
				frozenTrailEnabled = ParseBoolOrDefault(text4, frozenTrailEnabled);
				break;
			case "impact_preview_enabled":
				impactPreviewEnabled = ParseBoolOrDefault(text4, impactPreviewEnabled);
				break;
			case "impact_preview_fps":
				impactPreviewTargetFps = ParseFloatOrDefault(text4, impactPreviewTargetFps, 0f, 360f);
				break;
			case "impact_preview_width":
				impactPreviewTextureWidth = ParseIntOrDefault(text4, impactPreviewTextureWidth, 320, 3840);
				break;
			case "impact_preview_height":
				impactPreviewTextureHeight = ParseIntOrDefault(text4, impactPreviewTextureHeight, 180, 2160);
				break;
			case "actual_trail_start_width":
				actualTrailStartWidth = ParseFloatOrDefault(text4, actualTrailStartWidth, 0.005f, 1f);
				break;
			case "actual_trail_end_width":
				actualTrailEndWidth = ParseFloatOrDefault(text4, actualTrailEndWidth, 0.005f, 1f);
				break;
			case "predicted_trail_start_width":
				predictedTrailStartWidth = ParseFloatOrDefault(text4, predictedTrailStartWidth, 0.005f, 1f);
				break;
			case "predicted_trail_end_width":
				predictedTrailEndWidth = ParseFloatOrDefault(text4, predictedTrailEndWidth, 0.005f, 1f);
				break;
			case "frozen_trail_start_width":
				frozenTrailStartWidth = ParseFloatOrDefault(text4, frozenTrailStartWidth, 0.005f, 1f);
				break;
			case "frozen_trail_end_width":
				frozenTrailEndWidth = ParseFloatOrDefault(text4, frozenTrailEndWidth, 0.005f, 1f);
				break;
			case "actual_trail_color":
				actualTrailColor = ParseColorOrDefault(text4, actualTrailColor);
				break;
			case "predicted_trail_color":
				predictedTrailColor = ParseColorOrDefault(text4, predictedTrailColor);
				break;
			case "frozen_trail_color":
				frozenTrailColor = ParseColorOrDefault(text4, frozenTrailColor);
				break;
			case "hostallowedfeaturemask":
			{
				if (ulong.TryParse(text4, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
				{
					hostAllowedFeatureMask = result;
				}
				break;
			}
			}
		}
	}

	private string BuildDefaultConfigText()
	{
		StringBuilder stringBuilder = new StringBuilder(512);
		stringBuilder.AppendLine("# Birdie Mod config");
		stringBuilder.AppendLine("# Restart the game after editing this file for trail/visual settings.");
		stringBuilder.AppendLine("# Keybind and HUD changes can also be made in-game via the settings panel (F6).");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("assist_toggle_key=F1");
		stringBuilder.AppendLine("coffee_boost_key=F2");
		stringBuilder.AppendLine("nearest_ball_mode_key=F3");
		stringBuilder.AppendLine("unlock_all_cosmetics_key=F4");
		stringBuilder.AppendLine("item_spawner_key=F5");
		stringBuilder.AppendLine("hud_toggle_key=H");
		stringBuilder.AppendLine("random_item_key=G");
		stringBuilder.AppendLine("ice_toggle_key=I");
		stringBuilder.AppendLine("settings_key=F6");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("no_wind_key=W");
		stringBuilder.AppendLine("perfect_shot_key=P");
		stringBuilder.AppendLine("no_air_drag_key=D");
		stringBuilder.AppendLine("speed_multiplier_key=S");
		stringBuilder.AppendLine("speed_multiplier_factor=2.0");
		stringBuilder.AppendLine("infinite_ammo_key=A");
		stringBuilder.AppendLine("no_recoil_key=R");
		stringBuilder.AppendLine("no_knockback_key=K");
		stringBuilder.AppendLine("landmine_immunity_key=M");
		stringBuilder.AppendLine("lock_on_any_distance_key=L");
		stringBuilder.AppendLine("expanded_slots_key=U");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("hud_show_bottom_bar=true");
		stringBuilder.AppendLine("hud_show_ball_distance=true");
		stringBuilder.AppendLine("hud_show_ice_indicator=true");
		stringBuilder.AppendLine("hud_show_center_title=true");
		stringBuilder.AppendLine("hud_show_player_info=true");
		stringBuilder.AppendLine("tracers_enabled=true");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("credits_grant_amount=1000");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("actual_trail_enabled=true");
		stringBuilder.AppendLine("actual_trail_start_width=0.22");
		stringBuilder.AppendLine("actual_trail_end_width=0.18");
		stringBuilder.AppendLine("actual_trail_color=#FF9433");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("predicted_trail_enabled=true");
		stringBuilder.AppendLine("predicted_trail_start_width=0.18");
		stringBuilder.AppendLine("predicted_trail_end_width=0.14");
		stringBuilder.AppendLine("predicted_trail_color=#39F26E");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("frozen_trail_enabled=true");
		stringBuilder.AppendLine("frozen_trail_start_width=0.20");
		stringBuilder.AppendLine("frozen_trail_end_width=0.16");
		stringBuilder.AppendLine("frozen_trail_color=#53ACFF");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("impact_preview_enabled=true");
		stringBuilder.AppendLine("impact_preview_fps=60");
		stringBuilder.AppendLine("impact_preview_width=640");
		stringBuilder.AppendLine("impact_preview_height=360");
		return stringBuilder.ToString();
	}

	private string ParseKeyNameOrDefault(string value, string fallbackValue)
	{
		string text = ((value == null) ? "" : value.Trim());
		if (!string.IsNullOrEmpty(text))
		{
			return text;
		}
		return fallbackValue;
	}

	private bool ParseBoolOrDefault(string value, bool fallbackValue)
	{
		if (!bool.TryParse(value, out var result))
		{
			return fallbackValue;
		}
		return result;
	}

	private float ParseFloatOrDefault(string value, float fallbackValue, float minValue, float maxValue)
	{
		if (!float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
		{
			return fallbackValue;
		}
		return Mathf.Clamp(result, minValue, maxValue);
	}

	private int ParseIntOrDefault(string value, int fallbackValue, int minValue, int maxValue)
	{
		if (!int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
		{
			return fallbackValue;
		}
		return Mathf.Clamp(result, minValue, maxValue);
	}

	private Color ParseColorOrDefault(string value, Color fallbackValue)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: 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_0041: 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_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		Color result = default(Color);
		if (ColorUtility.TryParseHtmlString(value, ref result))
		{
			return result;
		}
		string[] array = value.Split(new char[1] { ',' });
		if (array.Length >= 3 && array.Length <= 4)
		{
			float[] array2 = new float[4] { fallbackValue.r, fallbackValue.g, fallbackValue.b, fallbackValue.a };
			for (int i = 0; i < array.Length; i++)
			{
				if (!float.TryParse(array[i].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
				{
					return fallbackValue;
				}
				array2[i] = ((result2 > 1f) ? Mathf.Clamp01(result2 / 255f) : Mathf.Clamp01(result2));
			}
			return new Color(array2[0], array2[1], array2[2], array2[3]);
		}
		return fallbackValue;
	}

	private void UpdateConfigLabels()
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: 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_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		assistToggleKey = ParseConfiguredKey(assistToggleKeyName, (Key)94);
		coffeeBoostKey = ParseConfiguredKey(coffeeBoostKeyName, (Key)95);
		nearestBallModeKey = ParseConfiguredKey(nearestBallModeKeyName, (Key)96);
		unlockAllCosmeticsKey = ParseConfiguredKey(unlockAllCosmeticsKeyName, (Key)97);
		itemSpawnerKey = ParseConfiguredKey(itemSpawnerKeyName, (Key)98);
		hudToggleKey = ParseConfiguredKey(hudToggleKeyName, (Key)22);
		randomItemKey = ParseConfiguredKey(randomItemKeyName, (Key)21);
		iceToggleKey = ParseConfiguredKey(iceToggleKeyName, (Key)23);
		settingsKey = ParseConfiguredKey(settingsKeyName, (Key)99);
		noWindKey = ParseConfiguredKey(noWindKeyName, (Key)37);
		perfectShotKey = ParseConfiguredKey(perfectShotKeyName, (Key)30);
		noAirDragKey = ParseConfiguredKey(noAirDragKeyName, (Key)18);
		speedMultiplierKey = ParseConfiguredKey(speedMultiplierKeyName, (Key)33);
		infiniteAmmoKey = ParseConfiguredKey(infiniteAmmoKeyName, (Key)15);
		noRecoilKey = ParseConfiguredKey(noRecoilKeyName, (Key)32);
		noKnockbackKey = ParseConfiguredKey(noKnockbackKeyName, (Key)25);
		landmineImmunityKey = ParseConfiguredKey(landmineImmunityKeyName, (Key)27);
		lockOnAnyDistanceKey = ParseConfiguredKey(lockOnAnyDistanceKeyName, (Key)26);
		expandedSlotsKey = ParseConfiguredKey(expandedSlotsKeyName, (Key)35);
		assistToggleKeyLabel = FormatKeyLabel(assistToggleKeyName);
		coffeeBoostKeyLabel = FormatKeyLabel(coffeeBoostKeyName);
		nearestBallModeKeyLabel = FormatKeyLabel(nearestBallModeKeyName);
		unlockAllCosmeticsKeyLabel = FormatKeyLabel(unlockAllCosmeticsKeyName);
		itemSpawnerKeyLabel = FormatKeyLabel(itemSpawnerKeyName);
		hudToggleKeyLabel = FormatKeyLabel(hudToggleKeyName);
		randomItemKeyLabel = FormatKeyLabel(randomItemKeyName);
		iceToggleKeyLabel = FormatKeyLabel(iceToggleKeyName);
		settingsKeyLabel = FormatKeyLabel(settingsKeyName);
		noWindKeyLabel = FormatKeyLabel(noWindKeyName);
		perfectShotKeyLabel = FormatKeyLabel(perfectShotKeyName);
		noAirDragKeyLabel = FormatKeyLabel(noAirDragKeyName);
		speedMultiplierKeyLabel = FormatKeyLabel(speedMultiplierKeyName);
		infiniteAmmoKeyLabel = FormatKeyLabel(infiniteAmmoKeyName);
		noRecoilKeyLabel = FormatKeyLabel(noRecoilKeyName);
		noKnockbackKeyLabel = FormatKeyLabel(noKnockbackKeyName);
		landmineImmunityKeyLabel = FormatKeyLabel(landmineImmunityKeyName);
		lockOnAnyDistanceKeyLabel = FormatKeyLabel(lockOnAnyDistanceKeyName);
		expandedSlotsKeyLabel = FormatKeyLabel(expandedSlotsKeyName);
	}

	private void SaveCurrentConfig()
	{
		try
		{
			string directoryName = Path.GetDirectoryName(configPath);
			if (!string.IsNullOrEmpty(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			File.WriteAllText(configPath, BuildCurrentConfigText(), Encoding.ASCII);
		}
		catch
		{
		}
	}

	private string BuildCurrentConfigText()
	{
		//IL_0394: Unknown result type (might be due to invalid IL or missing references)
		//IL_041a: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
		StringBuilder stringBuilder = new StringBuilder(1024);
		stringBuilder.AppendLine("# Birdie Mod config");
		stringBuilder.AppendLine("# Restart the game after editing this file for trail/visual settings.");
		stringBuilder.AppendLine("# Keybind and HUD changes can also be made in-game via the settings panel.");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("assist_toggle_key=" + assistToggleKeyName);
		stringBuilder.AppendLine("coffee_boost_key=" + coffeeBoostKeyName);
		stringBuilder.AppendLine("nearest_ball_mode_key=" + nearestBallModeKeyName);
		stringBuilder.AppendLine("unlock_all_cosmetics_key=" + unlockAllCosmeticsKeyName);
		stringBuilder.AppendLine("item_spawner_key=" + itemSpawnerKeyName);
		stringBuilder.AppendLine("hud_toggle_key=" + hudToggleKeyName);
		stringBuilder.AppendLine("random_item_key=" + randomItemKeyName);
		stringBuilder.AppendLine("ice_toggle_key=" + iceToggleKeyName);
		stringBuilder.AppendLine("settings_key=" + settingsKeyName);
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("no_wind_key=" + noWindKeyName);
		stringBuilder.AppendLine("perfect_shot_key=" + perfectShotKeyName);
		stringBuilder.AppendLine("no_air_drag_key=" + noAirDragKeyName);
		stringBuilder.AppendLine("speed_multiplier_key=" + speedMultiplierKeyName);
		stringBuilder.AppendLine("speed_multiplier_factor=" + speedMultiplierFactor.ToString(CultureInfo.InvariantCulture));
		stringBuilder.AppendLine("infinite_ammo_key=" + infiniteAmmoKeyName);
		stringBuilder.AppendLine("no_recoil_key=" + noRecoilKeyName);
		stringBuilder.AppendLine("no_knockback_key=" + noKnockbackKeyName);
		stringBuilder.AppendLine("landmine_immunity_key=" + landmineImmunityKeyName);
		stringBuilder.AppendLine("lock_on_any_distance_key=" + lockOnAnyDistanceKeyName);
		stringBuilder.AppendLine("expanded_slots_key=" + expandedSlotsKeyName);
		stringBuilder.AppendLine("expanded_slots_all_players=" + expandedSlotsAllPlayers.ToString().ToLowerInvariant());
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("hud_show_bottom_bar=" + hudShowBottomBar.ToString().ToLowerInvariant());
		stringBuilder.AppendLine("hud_show_ball_distance=" + hudShowBallDistance.ToString().ToLowerInvariant());
		stringBuilder.AppendLine("hud_show_ice_indicator=" + hudShowIceIndicator.ToString().ToLowerInvariant());
		stringBuilder.AppendLine("hud_show_center_title=" + hudShowCenterTitle.ToString().ToLowerInvariant());
		stringBuilder.AppendLine("hud_show_player_info=" + hudShowPlayerInfo.ToString().ToLowerInvariant());
		stringBuilder.AppendLine("tracers_enabled=" + tracersEnabled.ToString().ToLowerInvariant());
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("credits_grant_amount=" + creditsGrantAmount);
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("actual_trail_enabled=" + actualTrailEnabled.ToString().ToLowerInvariant());
		stringBuilder.AppendLine("actual_trail_start_width=" + actualTrailStartWidth.ToString(CultureInfo.InvariantCulture));
		stringBuilder.AppendLine("actual_trail_end_width=" + actualTrailEndWidth.ToString(CultureInfo.InvariantCulture));
		stringBuilder.AppendLine("actual_trail_color=#" + ColorUtility.ToHtmlStringRGB(actualTrailColor));
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("predicted_trail_enabled=" + predictedTrailEnabled.ToString().ToLowerInvariant());
		stringBuilder.AppendLine("predicted_trail_start_width=" + predictedTrailStartWidth.ToString(CultureInfo.InvariantCulture));
		stringBuilder.AppendLine("predicted_trail_end_width=" + predictedTrailEndWidth.ToString(CultureInfo.InvariantCulture));
		stringBuilder.AppendLine("predicted_trail_color=#" + ColorUtility.ToHtmlStringRGB(predictedTrailColor));
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("frozen_trail_enabled=" + frozenTrailEnabled.ToString().ToLowerInvariant());
		stringBuilder.AppendLine("frozen_trail_start_width=" + frozenTrailStartWidth.ToString(CultureInfo.InvariantCulture));
		stringBuilder.AppendLine("frozen_trail_end_width=" + frozenTrailEndWidth.ToString(CultureInfo.InvariantCulture));
		stringBuilder.AppendLine("frozen_trail_color=#" + ColorUtility.ToHtmlStringRGB(frozenTrailColor));
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("impact_preview_enabled=" + impactPreviewEnabled.ToString().ToLowerInvariant());
		stringBuilder.AppendLine("impact_preview_fps=" + ((int)impactPreviewTargetFps).ToString(CultureInfo.InvariantCulture));
		stringBuilder.AppendLine("impact_preview_width=" + impactPreviewTextureWidth.ToString(CultureInfo.InvariantCulture));
		stringBuilder.AppendLine("impact_preview_height=" + impactPreviewTextureHeight.ToString(CultureInfo.InvariantCulture));
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("hostAllowedFeatureMask=" + hostAllowedFeatureMask.ToString(CultureInfo.InvariantCulture));
		return stringBuilder.ToString();
	}

	private Key ParseConfiguredKey(string configuredKeyName, Key fallbackKey)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_001f: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrWhiteSpace(configuredKeyName))
		{
			return fallbackKey;
		}
		if (!Enum.TryParse<Key>(configuredKeyName.Trim(), ignoreCase: true, out Key result) || (int)result == 0)
		{
			return fallbackKey;
		}
		return result;
	}

	private string FormatKeyLabel(string configuredKeyName)
	{
		if (string.IsNullOrWhiteSpace(configuredKeyName))
		{
			return "?";
		}
		string text = configuredKeyName.Trim();
		if (Enum.TryParse<Key>(text, ignoreCase: true, out Key result))
		{
			text = ((object)(Key)(ref result)).ToString();
		}
		if (text.StartsWith("Digit", StringComparison.OrdinalIgnoreCase))
		{
			return text.Substring("Digit".Length);
		}
		return text.ToUpperInvariant();
	}

	private bool WasConfiguredKeyPressed(Key configuredKey)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		Keyboard current = Keyboard.current;
		if (current == null || (int)configuredKey == 0)
		{
			return false;
		}
		try
		{
			return current[configuredKey] != null && ((ButtonControl)current[configuredKey]).wasPressedThisFrame;
		}
		catch
		{
			return false;
		}
	}

	private Color BrightenColor(Color color, float factor)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		return new Color(Mathf.Clamp01(color.r * factor), Mathf.Clamp01(color.g * factor), Mathf.Clamp01(color.b * factor), color.a);
	}

	private Color DarkenColor(Color color, float factor)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		return new Color(Mathf.Clamp01(color.r * factor), Mathf.Clamp01(color.g * factor), Mathf.Clamp01(color.b * factor), color.a);
	}

	private Gradient CreateTrailGradient(Color baseColor, float startFactor, float midFactor, float endFactor, float startAlpha, float midAlpha, float endAlpha)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: 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_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: 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_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: 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_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: 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)
		Color val = BrightenColor(baseColor, startFactor);
		Color val2 = BrightenColor(baseColor, midFactor);
		Color val3 = DarkenColor(baseColor, endFactor);
		Gradient val4 = new Gradient();
		val4.colorKeys = (GradientColorKey[])(object)new GradientColorKey[3]
		{
			new GradientColorKey(val, 0f),
			new GradientColorKey(val2, 0.55f),
			new GradientColorKey(val3, 1f)
		};
		val4.alphaKeys = (GradientAlphaKey[])(object)new GradientAlphaKey[3]
		{
			new GradientAlphaKey(Mathf.Clamp01(startAlpha), 0f),
			new GradientAlphaKey(Mathf.Clamp01(midAlpha), 0.6f),
			new GradientAlphaKey(Mathf.Clamp01(endAlpha), 1f)
		};
		return val4;
	}

	private void ApplyTrailVisualSettings()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		ApplyTrailVisualSettings(shotPathLine, shotPathMaterial, actualTrailEnabled, actualTrailStartWidth, actualTrailEndWidth, actualTrailColor, 1.2f, 1f, 0.78f, 0.96f, 0.8f, 0.62f);
		ApplyTrailVisualSettings(predictedPathLine, predictedPathMaterial, predictedTrailEnabled, predictedTrailStartWidth, predictedTrailEndWidth, predictedTrailColor, 1.15f, 1f, 0.82f, 0.94f, 0.78f, 0.55f);
		ApplyTrailVisualSettings(frozenPredictedPathLine, frozenPredictedPathMaterial, frozenTrailEnabled, frozenTrailStartWidth, frozenTrailEndWidth, frozenTrailColor, 1.18f, 1f, 0.8f, 0.92f, 0.76f, 0.52f);
	}

	private void ApplyTrailVisualSettings(LineRenderer lineRenderer, Material material, bool enabled, float startWidth, float endWidth, Color baseColor, float startFactor, float midFactor, float endFactor, float startAlpha, float midAlpha, float endAlpha)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)lineRenderer == (Object)null))
		{
			lineRenderer.startWidth = startWidth;
			lineRenderer.endWidth = endWidth;
			((Renderer)lineRenderer).enabled = enabled;
			lineRenderer.colorGradient = CreateTrailGradient(baseColor, startFactor, midFactor, endFactor, startAlpha, midAlpha, endAlpha);
			if (!enabled)
			{
				lineRenderer.positionCount = 0;
			}
			if ((Object)(object)material != (Object)null)
			{
				material.color = baseColor;
			}
		}
	}

	private void ResolvePlayerContext()
	{
		Component val = playerMovement;
		Component val2 = playerGolfer;
		TryResolveLocalPlayerGolferViaGameManager();
		if ((Object)(object)playerMovement == (Object)null)
		{
			GameObject[] array = FindAllGameObjects();
			for (int i = 0; i < array.Length; i++)
			{
				GameObject val3 = array[i];
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				Component[] components = val3.GetComponents<Component>();
				foreach (Component val4 in components)
				{
					if (!((Object)(object)val4 == (Object)null) && !(((object)val4).GetType().Name != "PlayerMovement") && IsLocalPlayerMovement(val4))
					{
						playerMovement = val4;
						addSpeedBoostMethod = ((object)val4).GetType().GetMethod("AddSpeedBoost", BindingFlags.Instance | BindingFlags.NonPublic);
						i = array.Length;
						break;
					}
				}
			}
		}
		else if (addSpeedBoostMethod == null)
		{
			addSpeedBoostMethod = ((object)playerMovement).GetType().GetMethod("AddSpeedBoost", BindingFlags.Instance | BindingFlags.NonPublic);
		}
		EnsureLocalGolfBallReference(force: true);
		playerFound = (Object)(object)playerMovement != (Object)null && (Object)(object)playerGolfer != (Object)null;
		if (((Object)(object)val != (Object)null && val != playerMovement) || ((Object)(object)val2 != (Object)null && val2 != playerGolfer))
		{
			ClearRuntimeState();
		}
		hadResolvedPlayerContext = (Object)(object)playerMovement != (Object)null && (Object)(object)playerGolfer != (Object)null;
	}

	private bool IsLocalPlayerMovement(Component component)
	{
		try
		{
			PropertyInfo property = ((object)component).GetType().GetProperty("isLocalPlayer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			return property != null && property.PropertyType == typeof(bool) && (bool)property.GetValue(component, null);
		}
		catch
		{
			return false;
		}
	}

	private void CachePlayerGolferAccessors(Component golfer)
	{
		if (!((Object)(object)golfer == (Object)null))
		{
			EnsurePlayerGolferMetadataCached(golfer);
		}
	}

	private void EnsurePlayerGolferMetadataCached(Component golfer)
	{
		if ((Object)(object)golfer == (Object)null || initializedPlayerGolfer == golfer)
		{
			return;
		}
		initializedPlayerGolfer = golfer;
		playerGolferProperties.Clear();
		playerGolferFields.Clear();
		cachedTryStartChargingSwingMethod = null;
		cachedSetIsChargingSwingMethod = null;
		cachedReleaseSwingChargeMethod = null;
		cachedUpdateSwingNormalizedPowerMethod = null;
		swingNormalizedPowerBackingField = null;
		try
		{
			Type type = ((object)golfer).GetType();
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			string[] array = new string[6] { "SwingNormalizedPower", "SwingPitch", "IsChargingSwing", "IsSwinging", "IsAimingSwing", "OwnBall" };
			for (int i = 0; i < array.Length; i++)
			{
				PropertyInfo property = type.GetProperty(array[i], bindingAttr);
				if (property != null)
				{
					playerGolferProperties[array[i]] = property;
				}
			}
			string[] array2 = new string[1] { "swingPowerTimestamp" };
			for (int j = 0; j < array2.Length; j++)
			{
				FieldInfo field = type.GetField(array2[j], bindingAttr);
				if (field != null)
				{
					playerGolferFields[array2[j]] = field;
				}
			}
			cachedTryStartChargingSwingMethod = type.GetMethod("TryStartChargingSwing", bindingAttr);
			cachedSetIsChargingSwingMethod = type.GetMethod("SetIsChargingSwing", BindingFlags.Instance | BindingFlags.NonPublic);
			cachedReleaseSwingChargeMethod = type.GetMethod("ReleaseSwingCharge", bindingAttr);
			cachedUpdateSwingNormalizedPowerMethod = type.GetMethod("UpdateSwingNormalizedPower", BindingFlags.Instance | BindingFlags.NonPublic);
		}
		catch
		{
		}
	}

	private bool TryGetCurrentSwingValues(out float swingPower, out float swingPitch, out bool isChargingSwing, out bool isSwinging)
	{
		swingPower = idealSwingPower;
		swingPitch = idealSwingPitch;
		isChargingSwing = false;
		isSwinging = false;
		if ((Object)(object)playerGolfer == (Object)null)
		{
			return false;
		}
		try
		{
			if (!playerGolferProperties.TryGetValue("SwingNormalizedPower", out var value) || !playerGolferProperties.TryGetValue("SwingPitch", out var value2) || !playerGolferProperties.TryGetValue("IsChargingSwing", out var value3) || !playerGolferProperties.TryGetValue("IsSwinging", out var value4))
			{
				return false;
			}
			swingPower = Convert.ToSingle(value.GetValue(playerGolfer, null));
			swingPitch = Convert.ToSingle(value2.GetValue(playerGolfer, null));
			isChargingSwing = Convert.ToBoolean(value3.GetValue(playerGolfer, null));
			isSwinging = Convert.ToBoolean(value4.GetValue(playerGolfer, null));
			return true;
		}
		catch
		{
			return false;
		}
	}

	private void InitializeLocalGolferResolver()
	{
		if (localGolferResolverInitialized)
		{
			return;
		}
		localGolferResolverInitialized = true;
		try
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				Type type = assemblies[i].GetType("GameManager");
				if (!(type == null))
				{
					PropertyInfo property = type.GetProperty("LocalPlayerAsGolfer", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (property != null)
					{
						cachedLocalPlayerAsGolferProperty = property;
						break;
					}
				}
			}
		}
		catch
		{
		}
	}

	private bool TryResolveLocalPlayerGolferViaGameManager()
	{
		InitializeLocalGolferResolver();
		if (cachedLocalPlayerAsGolferProperty == null)
		{
			return false;
		}
		try
		{
			object? value = cachedLocalPlayerAsGolferProperty.GetValue(null, null);
			Component val = (Component)((value is Component) ? value : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (playerGolfer != val)
			{
				playerGolfer = val;
				CachePlayerGolferAccessors(val);
			}
			return true;
		}
		catch
		{
			return false;
		}
	}

	private bool EnsureLocalGolfBallReference(bool force)
	{
		if (nearestAnyBallModeEnabled)
		{
			return EnsureNearestAnyGolfBallReference(force);
		}
		if (!force && (Object)(object)golfBall != (Object)null && (Object)(object)golfBall.gameObject != (Object)null)
		{
			hadResolvedBallContext = true;
			return true;
		}
		float time = Time.time;
		if (!force && time < nextBallResolveTime)
		{
			return (Object)(object)golfBall != (Object)null;
		}
		nextBallResolveTime = time + ballResolveInterval;
		Component ownBall = null;
		string text = "missing";
		TryResolveLocalPlayerGolferViaGameManager();
		if (TryGetOwnBallFromGolfer(playerGolfer, out ownBall))
		{
			text = "OwnBall";
		}
		if ((Object)(object)ownBall == (Object)null)
		{
			HandleTrackedGolfBallChanged(golfBall, null);
			golfBall = null;
			lastBallResolveSource = "missing";
			hadResolvedBallContext = false;
			return false;
		}
		HandleTrackedGolfBallChanged(golfBall, ownBall);
		golfBall = ownBall;
		lastBallResolveSource = text;
		hadResolvedBallContext = true;
		return true;
	}

	private bool EnsureNearestAnyGolfBallReference(bool force)
	{
		if ((Object)(object)playerMovement == (Object)null && (Object)(object)playerGolfer == (Object)null)
		{
			golfBall = null;
			lastBallResolveSource = "missing";
			hadResolvedBallContext = false;
			return false;
		}
		float time = Time.time;
		if (!force && (Object)(object)golfBall != (Object)null && (Object)(object)golfBall.gameObject != (Object)null && time < nextNearestAnyBallResolveTime)
		{
			hadResolvedBallContext = true;
			return true;
		}
		nextNearestAnyBallResolveTime = time + nearestAnyBallResolveInterval;
		Component val = FindNearestGolfBallToPlayer(force);
		if ((Object)(object)val == (Object)null)
		{
			HandleTrackedGolfBallChanged(golfBall, null);
			golfBall = null;
			lastBallResolveSource = "missing";
			hadResolvedBallContext = false;
			return false;
		}
		HandleTrackedGolfBallChanged(golfBall, val);
		golfBall = val;
		lastBallResolveSource = "nearest-any";
		hadResolvedBallContext = true;
		return true;
	}

	private void HandleTrackedGolfBallChanged(Component previousBall, Component nextBall)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: 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_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		if (previousBall != nextBall)
		{
			ResetTrailState();
			HideImpactPreview();
			nextPredictedPathRefreshTime = 0f;
			swingHittableReflectionInitialized = false;
			lastShotPathBallPosition = (((Object)(object)nextBall != (Object)null) ? (nextBall.transform.position + Vector3.up * shotPathHeightOffset) : Vector3.zero);
		}
	}

	private void RefreshGolfBallCache(bool force)
	{
		float time = Time.time;
		if (!force && time < nextGolfBallCacheRefreshTime)
		{
			return;
		}
		cachedGolfBalls.Clear();
		Component[] array = FindAllComponents();
		foreach (Component val in array)
		{
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.gameObject == (Object)null) && !(((object)val).GetType().Name != "GolfBall"))
			{
				cachedGolfBalls.Add(val);
			}
		}
		nextGolfBallCacheRefreshTime = time + ((cachedGolfBalls.Count > 0) ? golfBallCacheRefreshInterval : emptyGolfBallCacheRefreshInterval);
	}

	private Component FindNearestGolfBallToPlayer(bool forceRefreshCache)
	{
		//IL_0019: 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_003a: Unknown result type (might be due to invalid I