Decompiled source of Rains Car Mod v1.0.3

RainsCarMod.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using FishNet;
using FishNet.Connection;
using FishNet.Object;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using RainsCarMod;
using RainsCarMod.Logging;
using ScheduleOne.DevUtilities;
using ScheduleOne.Interaction;
using ScheduleOne.Money;
using ScheduleOne.PlayerScripts;
using ScheduleOne.Vehicles;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(CarModLoader), "RainsCarMod", "1.0.3", "RainingDeath", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RainsCarMod")]
[assembly: AssemblyConfiguration("DebugMelon")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RainsCarMod")]
[assembly: AssemblyTitle("RainsCarMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RainsCarMod
{
	public class CarDealerInterface : MonoBehaviour
	{
		[Header("References")]
		public Transform cameraPosition;

		public InteractableObject intObj;

		public Canvas canvas;

		public static Action OnUIRequested;

		private bool isOpen = false;

		private PlayerMovement playerMovement;

		private PlayerCamera playerCamera;

		private PlayerInventory playerInventory;

		private void Start()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0090: 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)
			if ((Object)(object)intObj != (Object)null)
			{
				intObj.onInteractStart.AddListener(new UnityAction(Interacted));
			}
			GameObject val = GameObject.Find("Player_Local");
			if ((Object)(object)val != (Object)null)
			{
				playerMovement = val.GetComponent<PlayerMovement>();
				playerCamera = val.GetComponentInChildren<PlayerCamera>();
				playerInventory = val.GetComponentInChildren<PlayerInventory>();
			}
			if ((Object)(object)cameraPosition != (Object)null)
			{
				cameraPosition.position = new Vector3(-59.7f, -1.03f, -16.8f);
				cameraPosition.rotation = Quaternion.Euler(0f, 330f, 0f);
			}
			if ((Object)(object)canvas != (Object)null)
			{
				Transform val2 = ((Component)canvas).transform.Find("Panel");
				if ((Object)(object)val2 != (Object)null)
				{
					((Component)val2).gameObject.SetActive(true);
				}
			}
			UIManager.OnUICloseRequested = Close;
		}

		public void Interacted()
		{
			if (!isOpen)
			{
				Open();
			}
		}

		public void Open()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			isOpen = true;
			OnUIRequested?.Invoke();
			if ((Object)(object)playerMovement != (Object)null)
			{
				playerMovement.canMove = false;
			}
			if ((Object)(object)playerInventory != (Object)null)
			{
				playerInventory.SetInventoryEnabled(false);
			}
			if ((Object)(object)playerCamera != (Object)null && (Object)(object)cameraPosition != (Object)null)
			{
				playerCamera.FreeMouse();
				playerCamera.OverrideTransform(cameraPosition.position, cameraPosition.rotation, 0.15f, false);
				playerCamera.OverrideFOV(65f, 0.15f);
				playerCamera.AddActiveUIElement(((Object)this).name);
			}
		}

		public void Close()
		{
			isOpen = false;
			if ((Object)(object)playerMovement != (Object)null)
			{
				playerMovement.canMove = true;
			}
			if ((Object)(object)playerInventory != (Object)null)
			{
				playerInventory.SetInventoryEnabled(true);
			}
			if ((Object)(object)playerCamera != (Object)null)
			{
				playerCamera.StopTransformOverride(0.15f, true, true);
				playerCamera.StopFOVOverride(0.15f);
				playerCamera.LockMouse();
				playerCamera.RemoveActiveUIElement(((Object)this).name);
			}
		}
	}
	public class Core : MelonMod
	{
		public override void OnInitializeMelon()
		{
			Log.LogInfo("Initializing RainsCarMod...");
		}
	}
	public class DealerConfig
	{
		public bool enableDealership = true;

		public static DealerConfig Instance;

		public static void Load()
		{
			string text = Path.Combine(MelonEnvironment.UserDataDirectory, "RainsCarMod");
			string path = Path.Combine(text, "Dealer_Config.json");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			if (!File.Exists(path))
			{
				Instance = new DealerConfig();
				File.WriteAllText(path, JsonConvert.SerializeObject((object)Instance, (Formatting)1));
				MelonLogger.Msg("[RainsCarMod] Created default Dealer_Config.json");
				return;
			}
			try
			{
				string text2 = File.ReadAllText(path);
				Instance = JsonConvert.DeserializeObject<DealerConfig>(text2) ?? new DealerConfig();
				MelonLogger.Msg("[RainsCarMod] Loaded Dealer_Config.json");
			}
			catch
			{
				MelonLogger.Warning("[RainsCarMod] Failed to parse Dealer_Config.json, using defaults.");
				Instance = new DealerConfig();
			}
		}
	}
	public class CarModLoader : MelonMod
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass9_0
		{
			public string prefabKey;

			internal bool <RegisterModdedVehicles>b__0(LandVehicle v)
			{
				return (Object)(object)v != (Object)null && ((Object)v).name == prefabKey;
			}
		}

		[CompilerGenerated]
		private sealed class <InjectAndAssignCarDealerInterface>d__13 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public CarModLoader <>4__this;

			private GameObject <go>5__1;

			private Type <type>5__2;

			private Component <comp>5__3;

			private Component <intObj>5__4;

			private Component <canvas>5__5;

			private Transform <camPos>5__6;

			private FieldInfo <field>5__7;

			private EventInfo <eventInfo>5__8;

			private EventInfo <onEnd>5__9;

			private MethodInfo <method>5__10;

			private Delegate <del>5__11;

			private MethodInfo <method>5__12;

			private Delegate <del>5__13;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InjectAndAssignCarDealerInterface>d__13(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<go>5__1 = null;
				<type>5__2 = null;
				<comp>5__3 = null;
				<intObj>5__4 = null;
				<canvas>5__5 = null;
				<camPos>5__6 = null;
				<field>5__7 = null;
				<eventInfo>5__8 = null;
				<onEnd>5__9 = null;
				<method>5__10 = null;
				<del>5__11 = null;
				<method>5__12 = null;
				<del>5__13 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<go>5__1 = GameObject.Find("CarDealerComputer");
					if ((Object)(object)<go>5__1 == (Object)null)
					{
						MelonLogger.Error("❌ Could not find CarDealerComputer in scene.");
						return false;
					}
					if ((Object)(object)<go>5__1.GetComponent<UIManager>() == (Object)null)
					{
						<go>5__1.AddComponent<UIManager>();
						MelonLogger.Msg("\ud83e\udde9 Attached UIManager to CarDealerComputer.");
					}
					<type>5__2 = Type.GetType("RainsCarMod.CarDealerInterface, RainsCarMod");
					if (<type>5__2 == null)
					{
						MelonLogger.Error("❌ CarDealerInterface type not found.");
						return false;
					}
					<comp>5__3 = <go>5__1.AddComponent(<type>5__2);
					<intObj>5__4 = <go>5__1.GetComponent("InteractableObject");
					<canvas>5__5 = <go>5__1.GetComponentInChildren(typeof(Canvas), true);
					<camPos>5__6 = <go>5__1.transform.Find("CameraPosition");
					<type>5__2.GetField("intObj")?.SetValue(<comp>5__3, <intObj>5__4);
					<type>5__2.GetField("canvas")?.SetValue(<comp>5__3, <canvas>5__5);
					<type>5__2.GetField("cameraPosition")?.SetValue(<comp>5__3, <camPos>5__6);
					if ((Object)(object)<intObj>5__4 != (Object)null)
					{
						<eventInfo>5__8 = ((object)<intObj>5__4).GetType().GetEvent("onInteractStart");
						if (<eventInfo>5__8 != null)
						{
							<method>5__10 = <type>5__2.GetMethod("Interacted");
							<del>5__11 = Delegate.CreateDelegate(<eventInfo>5__8.EventHandlerType, <comp>5__3, <method>5__10);
							<eventInfo>5__8.AddEventHandler(<intObj>5__4, <del>5__11);
							<method>5__10 = null;
							<del>5__11 = null;
						}
						<onEnd>5__9 = ((object)<intObj>5__4).GetType().GetEvent("onInteractEnd");
						if (<onEnd>5__9 != null)
						{
							<method>5__12 = <type>5__2.GetMethod("Close");
							<del>5__13 = Delegate.CreateDelegate(<onEnd>5__9.EventHandlerType, <comp>5__3, <method>5__12);
							<onEnd>5__9.AddEventHandler(<intObj>5__4, <del>5__13);
							<method>5__12 = null;
							<del>5__13 = null;
						}
						<eventInfo>5__8 = null;
						<onEnd>5__9 = null;
					}
					<field>5__7 = <type>5__2.GetField("OnUIRequested");
					if (<field>5__7 != null)
					{
						<field>5__7.SetValue(null, (Action)delegate
						{
							GameObject val = GameObject.Find("CarDealerComputer");
							if ((Object)(object)val == (Object)null)
							{
								MelonLogger.Warning("⚠\ufe0f Could not find CarDealerComputer.");
							}
							else
							{
								UIManager componentInChildren = val.GetComponentInChildren<UIManager>(true);
								if ((Object)(object)componentInChildren != (Object)null)
								{
									componentInChildren.ShowUI();
								}
								else
								{
									MelonLogger.Warning("⚠\ufe0f UIManager not found on CarDealerComputer.");
								}
							}
						});
					}
					MelonLogger.Msg("✅ Fully injected CarDealerInterface and interaction events.");
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <InjectMapExtension>d__10 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public CarModLoader <>4__this;

			private GameObject <buildingPrefab>5__1;

			private GameObject <building>5__2;

			private GameObject <computerPrefab>5__3;

			private GameObject <computer>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InjectMapExtension>d__10(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<buildingPrefab>5__1 = null;
				<building>5__2 = null;
				<computerPrefab>5__3 = null;
				<computer>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (!LoadedPrefabs.TryGetValue("CarDealership", out <buildingPrefab>5__1))
					{
						MelonLogger.Error("❌ CarDealership prefab not found.");
						return false;
					}
					<building>5__2 = Object.Instantiate<GameObject>(<buildingPrefab>5__1, mapExtensionPosition, mapExtensionRotation);
					((Object)<building>5__2).name = "CarDealership";
					<>4__this.SetAllChildrenActive(<building>5__2, state: true);
					MelonLogger.Msg("\ud83c\udfd7\ufe0f Injected CarDealership into scene.");
					if (!LoadedPrefabs.TryGetValue("CarDealerComputer", out <computerPrefab>5__3))
					{
						MelonLogger.Error("❌ CarDealerComputer prefab not found.");
						return false;
					}
					<computer>5__4 = Object.Instantiate<GameObject>(<computerPrefab>5__3, new Vector3(-60.05f, -1.05f, -16.22f), Quaternion.Euler(0f, 150f, 0f));
					((Object)<computer>5__4).name = "CarDealerComputer";
					<computer>5__4.SetActive(true);
					MelonLogger.Msg("\ud83d\udcbb Injected CarDealerComputer.");
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <RegisterModdedVehicles>d__9 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public CarModLoader <>4__this;

			private Dictionary<string, GameObject>.Enumerator <>s__1;

			private KeyValuePair<string, GameObject> <kvp>5__2;

			private <>c__DisplayClass9_0 <>8__3;

			private GameObject <prefab>5__4;

			private LandVehicle <landVehicle>5__5;

			private NetworkObject <netObj>5__6;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RegisterModdedVehicles>d__9(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>s__1 = default(Dictionary<string, GameObject>.Enumerator);
				<kvp>5__2 = default(KeyValuePair<string, GameObject>);
				<>8__3 = null;
				<prefab>5__4 = null;
				<landVehicle>5__5 = null;
				<netObj>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>s__1 = LoadedPrefabs.GetEnumerator();
					try
					{
						while (<>s__1.MoveNext())
						{
							<kvp>5__2 = <>s__1.Current;
							<>8__3 = new <>c__DisplayClass9_0();
							<>8__3.prefabKey = <kvp>5__2.Key;
							<prefab>5__4 = <kvp>5__2.Value;
							if ((Object)(object)NetworkSingleton<VehicleManager>.Instance == (Object)null)
							{
								MelonLogger.Error("❌ VehicleManager.Instance is still null after delay.");
								return false;
							}
							if (NetworkSingleton<VehicleManager>.Instance.VehiclePrefabs.Any((LandVehicle v) => (Object)(object)v != (Object)null && ((Object)v).name == <>8__3.prefabKey))
							{
								continue;
							}
							<landVehicle>5__5 = <prefab>5__4.GetComponent<LandVehicle>();
							if ((Object)(object)<landVehicle>5__5 != (Object)null)
							{
								((Object)<prefab>5__4).name = <>8__3.prefabKey;
								<landVehicle>5__5.vehicleName = <>8__3.prefabKey;
								NetworkSingleton<VehicleManager>.Instance.VehiclePrefabs.Add(<landVehicle>5__5);
								<netObj>5__6 = <prefab>5__4.GetComponent<NetworkObject>();
								if ((Object)(object)<netObj>5__6 != (Object)null)
								{
									InstanceFinder.NetworkManager.SpawnablePrefabs.AddObject(<netObj>5__6, false);
								}
								<netObj>5__6 = null;
							}
							<>8__3 = null;
							<prefab>5__4 = null;
							<landVehicle>5__5 = null;
							<kvp>5__2 = default(KeyValuePair<string, GameObject>);
						}
					}
					finally
					{
						((IDisposable)<>s__1).Dispose();
					}
					<>s__1 = default(Dictionary<string, GameObject>.Enumerator);
					MelonLogger.Msg("✅ Registered all modded vehicles.");
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const float labelHeightAboveDesk = 1f;

		public static readonly Dictionary<string, GameObject> LoadedPrefabs = new Dictionary<string, GameObject>();

		private GameObject carUIRoot;

		public static readonly Vector3 mapExtensionPosition = new Vector3(-51.5491f, 19.9f, -27.9102f);

		public static readonly Quaternion mapExtensionRotation = Quaternion.Euler(270f, 150f, 0f);

		public static readonly Vector3 carSpawnPosition = new Vector3(-46.45f, -1.5f, -31.62f);

		public static readonly Quaternion carSpawnRotation = Quaternion.Euler(0f, 210f, 0f);

		public override void OnApplicationStart()
		{
			DealerConfig.Load();
			LoadEmbeddedBundle();
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (!(sceneName != "Main"))
			{
				if (!DealerConfig.Instance.enableDealership)
				{
					MelonLogger.Msg("[RainsCarMod] \ud83d\udeab Dealership injection disabled by config.");
					return;
				}
				MelonCoroutines.Start(InjectMapExtension());
				MelonCoroutines.Start(RegisterModdedVehicles());
				MelonCoroutines.Start(InjectAndAssignCarDealerInterface());
			}
		}

		[IteratorStateMachine(typeof(<RegisterModdedVehicles>d__9))]
		private IEnumerator RegisterModdedVehicles()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RegisterModdedVehicles>d__9(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<InjectMapExtension>d__10))]
		private IEnumerator InjectMapExtension()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InjectMapExtension>d__10(0)
			{
				<>4__this = this
			};
		}

		private void SetAllChildrenActive(GameObject parent, bool state)
		{
			Transform[] componentsInChildren = parent.GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				((Component)val).gameObject.SetActive(state);
			}
		}

		private void LoadEmbeddedBundle()
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream("RainsCarMod.Resources.carmod");
			if (stream == null)
			{
				MelonLogger.Error("❌ Could not find embedded carmod bundle.");
				return;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			AssetBundle val = AssetBundle.LoadFromMemory(memoryStream.ToArray());
			GameObject[] array = val.LoadAllAssets<GameObject>();
			foreach (GameObject val2 in array)
			{
				if (!LoadedPrefabs.ContainsKey(((Object)val2).name))
				{
					LoadedPrefabs[((Object)val2).name] = val2;
				}
			}
			MelonLogger.Msg("✅ Loaded car prefabs from bundle.");
		}

		[IteratorStateMachine(typeof(<InjectAndAssignCarDealerInterface>d__13))]
		private IEnumerator InjectAndAssignCarDealerInterface()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InjectAndAssignCarDealerInterface>d__13(0)
			{
				<>4__this = this
			};
		}
	}
	[Serializable]
	public class VehiclePriceEntry
	{
		public string name;

		public int price;
	}
	[Serializable]
	public class VehiclePriceWrapper
	{
		public List<VehiclePriceEntry> Entries;

		public Dictionary<string, int> ToDictionary()
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			if (Entries != null)
			{
				foreach (VehiclePriceEntry entry in Entries)
				{
					if (!string.IsNullOrEmpty(entry.name))
					{
						dictionary[entry.name.Replace(" ", "_")] = entry.price;
					}
				}
			}
			return dictionary;
		}
	}
	public class UIManager : MonoBehaviour
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__15_0;

			internal void <AddCloseListener>b__15_0()
			{
				OnUICloseRequested?.Invoke();
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
			}
		}

		private string pendingPrefabKey = null;

		private GameObject confirmPopup;

		private TextMeshProUGUI confirmText;

		private static TMP_FontAsset liberationFont;

		private static Dictionary<string, int> VehiclePrices = new Dictionary<string, int>();

		public static Action OnUICloseRequested;

		private Transform uiRoot;

		private Image vehicleIconImage;

		private void Start()
		{
			if (!DealerConfig.Instance.enableDealership)
			{
				MelonLogger.Msg("\ud83d\udee1\ufe0f UIManager.Start skipped because dealership is disabled.");
				return;
			}
			uiRoot = ((Component)this).transform.Find("Panel");
			if ((Object)(object)uiRoot == (Object)null)
			{
				MelonLogger.Error("❌ UI root panel not found under CarDealerComputer.");
				return;
			}
			liberationFont = Resources.Load<TMP_FontAsset>("Fonts & Materials/LiberationSans SDF");
			if ((Object)(object)liberationFont == (Object)null)
			{
				MelonLogger.Warning("❌ Could not load LiberationSans SDF font.");
			}
			FixInsufficientFundsPopupFont();
			SetupConfirmPopup();
			LoadVehiclePricesFromJson();
			AddButtonListener("Buy Bugatti Tourbillon", "Bugatti_Tourbillon");
			AddButtonListener("Buy GTR R35", "GTR_R35");
			AddButtonListener("Buy GTR R34", "GTR_R34");
			AddButtonListener("Buy Demon", "Demon");
			AddButtonListener("Buy Rolls Royce Ghost", "Rolls_Royce_Ghost");
			AddButtonListener("Buy Driftcar", "driftcar");
			AddButtonListener("Buy Supercar", "supercar");
			AddButtonListener("Buy Soup Car", "canofsoupcar");
			AddButtonListener("Buy Lamborghini Veneno", "Lamborghini_Veneno");
			AddButtonListener("Buy Cyber Truck", "Cyber_Truck");
			AddButtonListener("Buy Koenigsegg CC850", "Koenigsegg_CC850");
			AddButtonListener("Buy Lancia Delta", "Lancia_Delta");
			AddButtonListener("Buy El Camino", "El_Camino");
			AddCloseListener("Close");
		}

		private void SetupConfirmPopup()
		{
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Expected O, but got Unknown
			Transform obj = FindDeepChild(((Component)this).transform, "PurchaseConfirmPopup");
			confirmPopup = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)confirmPopup == (Object)null)
			{
				MelonLogger.Error("❌ PurchaseConfirmPopup not found.");
				return;
			}
			confirmPopup.SetActive(false);
			Transform obj2 = FindDeepChild(confirmPopup.transform, "ConfirmPurchaseText");
			confirmText = ((obj2 != null) ? ((Component)obj2).GetComponent<TextMeshProUGUI>() : null);
			if ((Object)(object)confirmText != (Object)null && (Object)(object)liberationFont != (Object)null)
			{
				((TMP_Text)confirmText).font = liberationFont;
				((TMP_Text)confirmText).fontSize = 28f;
			}
			Transform obj3 = FindDeepChild(confirmPopup.transform, "VehicleIcon");
			vehicleIconImage = ((obj3 != null) ? ((Component)obj3).GetComponent<Image>() : null);
			if ((Object)(object)vehicleIconImage == (Object)null)
			{
				MelonLogger.Warning("⚠\ufe0f VehicleIcon image not found inside PurchaseConfirmPopup.");
			}
			Transform obj4 = FindDeepChild(confirmPopup.transform, "ConfirmPurchaseButton");
			Button val = ((obj4 != null) ? ((Component)obj4).GetComponent<Button>() : null);
			if ((Object)(object)val != (Object)null)
			{
				((UnityEvent)val.onClick).AddListener(new UnityAction(ConfirmPurchase));
				TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(true);
				if ((Object)(object)componentInChildren != (Object)null && (Object)(object)liberationFont != (Object)null)
				{
					((TMP_Text)componentInChildren).font = liberationFont;
					((TMP_Text)componentInChildren).text = "Confirm Purchase";
				}
			}
			Transform obj5 = FindDeepChild(confirmPopup.transform, "CancelPurchaseButton");
			Button val2 = ((obj5 != null) ? ((Component)obj5).GetComponent<Button>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
				{
					confirmPopup.SetActive(false);
					pendingPrefabKey = null;
				});
				TextMeshProUGUI componentInChildren2 = ((Component)val2).GetComponentInChildren<TextMeshProUGUI>(true);
				if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)liberationFont != (Object)null)
				{
					((TMP_Text)componentInChildren2).font = liberationFont;
					((TMP_Text)componentInChildren2).text = "Cancel Purchase";
				}
			}
		}

		private void ConfirmPurchase()
		{
			confirmPopup.SetActive(false);
			if (!string.IsNullOrEmpty(pendingPrefabKey))
			{
				if (!VehiclePrices.TryGetValue(pendingPrefabKey, out var value))
				{
					value = 500;
				}
				MoneyManager instance = NetworkSingleton<MoneyManager>.Instance;
				if (instance.cashBalance < (float)value)
				{
					ShowInsufficientFundsMessage();
					return;
				}
				TrySpawnVehicle(pendingPrefabKey, InstanceFinder.ClientManager.Connection);
				OnUICloseRequested?.Invoke();
				pendingPrefabKey = null;
			}
		}

		public void ShowUI()
		{
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)0;
		}

		private void ShowInsufficientFundsMessage()
		{
			Transform val = FindDeepChild(((Component)this).transform, "InsufficientFundsPopup");
			if (!((Object)(object)val == (Object)null))
			{
				((Component)val).gameObject.SetActive(true);
				((Component)val).transform.SetAsLastSibling();
				Canvas val2 = ((Component)val).GetComponent<Canvas>() ?? ((Component)val).gameObject.AddComponent<Canvas>();
				val2.overrideSorting = true;
				val2.sortingOrder = 10000;
				((MonoBehaviour)this).Invoke("HideInsufficientFundsMessage", 1f);
			}
		}

		private void HideInsufficientFundsMessage()
		{
			Transform val = FindDeepChild(((Component)this).transform, "InsufficientFundsPopup");
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.SetActive(false);
			}
		}

		private void AddButtonListener(string buttonName, string prefabKey)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			Transform buttonGO = FindDeepChild(((Component)this).transform, buttonName);
			Button val = default(Button);
			if ((Object)(object)buttonGO == (Object)null || !((Component)buttonGO).TryGetComponent<Button>(ref val))
			{
				MelonLogger.Error("❌ Button not found: " + buttonName);
				return;
			}
			TextMeshProUGUI componentInChildren = ((Component)buttonGO).GetComponentInChildren<TextMeshProUGUI>();
			if ((Object)(object)componentInChildren != (Object)null && (Object)(object)liberationFont != (Object)null)
			{
				((TMP_Text)componentInChildren).font = liberationFont;
				((TMP_Text)componentInChildren).text = buttonName;
			}
			((UnityEvent)val.onClick).AddListener((UnityAction)delegate
			{
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				if (!VehiclePrices.TryGetValue(prefabKey, out var value))
				{
					value = 500;
				}
				pendingPrefabKey = prefabKey;
				Transform obj = FindDeepChild(((Component)buttonGO).transform, "VehicleIcon");
				Image val2 = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
				if ((Object)(object)val2 != (Object)null && (Object)(object)vehicleIconImage != (Object)null)
				{
					vehicleIconImage.sprite = val2.sprite;
					((Graphic)vehicleIconImage).color = Color.white;
					vehicleIconImage.preserveAspect = true;
				}
				if ((Object)(object)confirmText != (Object)null)
				{
					((TMP_Text)confirmText).text = string.Format("Purchase {0} for ${1:N0}?", prefabKey.Replace("_", " "), value);
				}
				GameObject obj2 = confirmPopup;
				if (obj2 != null)
				{
					obj2.SetActive(true);
				}
				confirmPopup.transform.SetAsLastSibling();
			});
		}

		private void AddCloseListener(string name)
		{
			//IL_008c: 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_0097: Expected O, but got Unknown
			Transform val = FindDeepChild(uiRoot, name);
			Button val2 = default(Button);
			if ((Object)(object)val == (Object)null || !((Component)val).TryGetComponent<Button>(ref val2))
			{
				MelonLogger.Error("❌ Close button not found.");
				return;
			}
			TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>();
			if ((Object)(object)componentInChildren != (Object)null && (Object)(object)liberationFont != (Object)null)
			{
				((TMP_Text)componentInChildren).font = liberationFont;
				((TMP_Text)componentInChildren).text = name;
			}
			ButtonClickedEvent onClick = val2.onClick;
			object obj = <>c.<>9__15_0;
			if (obj == null)
			{
				UnityAction val3 = delegate
				{
					OnUICloseRequested?.Invoke();
					Cursor.lockState = (CursorLockMode)1;
					Cursor.visible = false;
				};
				<>c.<>9__15_0 = val3;
				obj = (object)val3;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
		}

		private void LoadVehiclePricesFromJson()
		{
			try
			{
				string text = Path.Combine(MelonEnvironment.UserDataDirectory, "RainsCarMod");
				string path = Path.Combine(text, "VehiclePrices.json");
				if (!Directory.Exists(text))
				{
					Directory.CreateDirectory(text);
				}
				if (!File.Exists(path))
				{
					VehiclePriceWrapper vehiclePriceWrapper = new VehiclePriceWrapper
					{
						Entries = new List<VehiclePriceEntry>
						{
							new VehiclePriceEntry
							{
								name = "GTR R34",
								price = 60000
							},
							new VehiclePriceEntry
							{
								name = "GTR R35",
								price = 75000
							},
							new VehiclePriceEntry
							{
								name = "Demon",
								price = 70000
							},
							new VehiclePriceEntry
							{
								name = "Bugatti Tourbillon",
								price = 500000
							},
							new VehiclePriceEntry
							{
								name = "driftcar",
								price = 15000
							},
							new VehiclePriceEntry
							{
								name = "supercar",
								price = 100000
							},
							new VehiclePriceEntry
							{
								name = "canofsoupcar",
								price = 500
							},
							new VehiclePriceEntry
							{
								name = "Rolls Royce Ghost",
								price = 200000
							},
							new VehiclePriceEntry
							{
								name = "Lamborghini Veneno",
								price = 300000
							},
							new VehiclePriceEntry
							{
								name = "Cyber Truck",
								price = 55000
							},
							new VehiclePriceEntry
							{
								name = "Koenigsegg CC850",
								price = 360000
							},
							new VehiclePriceEntry
							{
								name = "Lancia_Delta",
								price = 80000
							},
							new VehiclePriceEntry
							{
								name = "El_Camino",
								price = 25000
							}
						}
					};
					File.WriteAllText(path, JsonConvert.SerializeObject((object)vehiclePriceWrapper, (Formatting)1));
					VehiclePrices = vehiclePriceWrapper.ToDictionary();
					MelonLogger.Msg("✅ Created default VehiclePrices.json");
				}
				else
				{
					VehiclePriceWrapper vehiclePriceWrapper2 = JsonConvert.DeserializeObject<VehiclePriceWrapper>(File.ReadAllText(path));
					if (vehiclePriceWrapper2?.Entries != null)
					{
						VehiclePrices = vehiclePriceWrapper2.ToDictionary();
						MelonLogger.Msg($"✅ Loaded {VehiclePrices.Count} vehicle prices.");
					}
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"❌ Error parsing VehiclePrices.json: {arg}");
			}
		}

		private void FixInsufficientFundsPopupFont()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			Transform val = FindDeepChild(((Component)this).transform, "InsufficientFundsPopup");
			if (!((Object)(object)val == (Object)null))
			{
				TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(true);
				if ((Object)(object)componentInChildren != (Object)null && (Object)(object)liberationFont != (Object)null)
				{
					((TMP_Text)componentInChildren).font = liberationFont;
					((TMP_Text)componentInChildren).fontSize = 32f;
					((Graphic)componentInChildren).color = Color.black;
				}
			}
		}

		public static void TrySpawnVehicle(string prefabKey, NetworkConnection conn)
		{
			//IL_008c: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			if (!InstanceFinder.IsServer)
			{
				return;
			}
			NetworkObject firstObject = conn.FirstObject;
			if ((Object)(object)firstObject == (Object)null)
			{
				return;
			}
			if (!VehiclePrices.TryGetValue(prefabKey, out var value))
			{
				value = 500;
			}
			MoneyManager instance = NetworkSingleton<MoneyManager>.Instance;
			if (!(instance.cashBalance < (float)value) && CarModLoader.LoadedPrefabs.TryGetValue(prefabKey, out var value2))
			{
				instance.ChangeCashBalance((float)(-value), true, false);
				GameObject val = Object.Instantiate<GameObject>(value2, CarModLoader.carSpawnPosition, CarModLoader.carSpawnRotation);
				InstanceFinder.ServerManager.Spawn(val, conn, default(Scene));
				LandVehicle component = val.GetComponent<LandVehicle>();
				if ((Object)(object)component != (Object)null && !NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Contains(component))
				{
					NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Add(component);
				}
				MelonLogger.Msg($"\ud83d\ude97 Spawned {prefabKey} for {conn.ClientId}");
			}
		}

		private Transform FindDeepChild(Transform parent, string name)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (((Object)val).name == name)
				{
					return val;
				}
				Transform val2 = FindDeepChild(val, name);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}
	}
}
namespace RainsCarMod.Logging
{
	public static class Log
	{
		public static void LogInfo(string message)
		{
			Melon<Core>.Logger.Msg(message);
		}

		public static void LogWarning(string message)
		{
			Melon<Core>.Logger.Warning(message);
		}

		public static void LogError(string message)
		{
			Melon<Core>.Logger.Error(message);
		}

		public static void LogFatal(string message)
		{
			Melon<Core>.Logger.BigError(message);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}