Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Rains Car Mod v1.0.3
RainsCarMod.dll
Decompiled 2 weeks agousing 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) { } } }