Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of AutoDistributor v1.1.6
Mods/AutoDistributor.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AutoDistributor; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Reflection; using MelonLoader; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(AutoDistributorMod), "Auto Distributor", "1.1.6", "Blazinggggg", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("AutoDistributor")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("AutoDistributor")] [assembly: AssemblyTitle("AutoDistributor")] [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 AutoDistributor { public class AutoDistributorMod : MelonMod { private bool _menuOpen; private Rect _windowRect; private bool _isResizing = false; private const float MIN_WIDTH = 750f; private const float MIN_HEIGHT = 500f; private const float MAX_WIDTH = 1400f; private const float MAX_HEIGHT = 1000f; private static float _savedWidth = 750f; private static float _savedHeight = 700f; private static bool _hasSavedSize = false; private DistSlot[] _distSlots = new DistSlot[10]; private HotbarSlotInfo[] _hotbarSlots = new HotbarSlotInfo[0]; private List<DealerInfo> _dealers = new List<DealerInfo>(); private Vector2 _dealerScrollPos; private string _statusMsg = ""; private float _statusTime; private bool _stylesInit; private GUIStyle _sEmpty; private GUIStyle _sFilled; private GUIStyle _sHeader; private GUIStyle _sStatus; private GUIStyle _sBtn; private GUIStyle _sHotbar; private GUIStyle _sHotbarFill; private GUIStyle _sDone; private GUIStyle _sPkgBaggie; private GUIStyle _sPkgJar; private GUIStyle _sPkgBrick; private GUIStyle _sSliderLabel; private float _maxPerDealer = 0f; private List<MonoBehaviour> _disabledScripts = new List<MonoBehaviour>(); private List<string> _distResults = new List<string>(); public override void OnInitializeMelon() { MelonLogger.Msg("[AutoDistributor] v1.1.6 Loaded – F10 to open"); } public override void OnUpdate() { if (Input.GetKeyDown((KeyCode)291)) { _menuOpen = !_menuOpen; if (_menuOpen) { Open(); } else { Close(); } } if (_menuOpen && Input.GetKeyDown((KeyCode)27)) { _menuOpen = false; Close(); } if (_menuOpen) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } public override void OnLateUpdate() { if (_menuOpen) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } private void Open() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) float num = (_hasSavedSize ? _savedWidth : 750f); float num2 = (_hasSavedSize ? _savedHeight : 700f); _windowRect = new Rect(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, num, num2); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; TogglePlayerControl(enable: false); _dealers = GameBridge.GetRecruitedDealers(); _hotbarSlots = GameBridge.ReadPlayerHotbar(); _distResults.Clear(); MelonLogger.Msg($"[AutoDistributor] Opened – {_dealers.Count} dealers, {_hotbarSlots.Length} hotbar slots"); } private void Close() { _savedWidth = ((Rect)(ref _windowRect)).width; _savedHeight = ((Rect)(ref _windowRect)).height; _hasSavedSize = true; for (int i = 0; i < _distSlots.Length; i++) { _distSlots[i] = null; } Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; TogglePlayerControl(enable: true); MelonLogger.Msg("[AutoDistributor] Closed"); } private void TogglePlayerControl(bool enable) { try { if (!enable) { _disabledScripts.Clear(); } List<GameObject> list = new List<GameObject>(); Camera main = Camera.main; if ((Object)(object)main != (Object)null) { list.Add(((Component)main).gameObject); if ((Object)(object)((Component)main).transform.parent != (Object)null) { list.Add(((Component)((Component)main).transform.parent).gameObject); } Transform parent = ((Component)main).transform.parent; if ((Object)(object)((parent != null) ? parent.parent : null) != (Object)null) { list.Add(((Component)((Component)main).transform.parent.parent).gameObject); } } string[] array = new string[4] { "Player_Local(Clone)", "Player(Clone)", "Player_Local", "Player" }; foreach (string text in array) { GameObject val = GameObject.Find(text); if ((Object)(object)val == (Object)null) { continue; } if (!list.Contains(val)) { list.Add(val); } Il2CppArrayBase<Transform> componentsInChildren = val.GetComponentsInChildren<Transform>(); if (componentsInChildren == null) { continue; } for (int j = 0; j < componentsInChildren.Count; j++) { if ((Object)(object)componentsInChildren[j] != (Object)null && !list.Contains(((Component)componentsInChildren[j]).gameObject)) { list.Add(((Component)componentsInChildren[j]).gameObject); } } } string[] array2 = new string[51] { "Look", "MouseLook", "CameraControl", "PlayerCamera", "CinemachineBrain", "FirstPerson", "PlayerMovement", "PlayerController", "InputManager", "PlayerInput", "Interact", "PlayerActions", "Combat", "Attack", "PlayerUse", "Hotbar", "ToolController", "HandController", "UseItem", "PlayerAction", "Punch", "Melee", "CrosshairManager", "PlayerInventory", "Shoot", "WeaponController", "ItemUseManager", "ItemUse", "Equippable", "Gun", "Firearm", "Weapon", "Fire", "Aim", "ADS", "Trigger", "Revolver", "Pistol", "Rifle", "Shotgun", "Holdable", "Held", "EquippedItem", "ArmAnimator", "ArmController", "PlayerArm", "PlayerHand", "Hand_", "Throwable", "Consumable", "Useable" }; if (!enable) { foreach (GameObject item in list) { if ((Object)(object)item == (Object)null) { continue; } Il2CppArrayBase<MonoBehaviour> components = item.GetComponents<MonoBehaviour>(); if (components == null) { continue; } for (int k = 0; k < components.Count; k++) { MonoBehaviour val2 = components[k]; if ((Object)(object)val2 == (Object)null || !((Behaviour)val2).enabled) { continue; } string name = ((MemberInfo)((Object)val2).GetIl2CppType()).Name; string[] array3 = array2; foreach (string value in array3) { if (name.Contains(value, StringComparison.OrdinalIgnoreCase)) { ((Behaviour)val2).enabled = false; _disabledScripts.Add(val2); break; } } } } string[] array4 = new string[13] { "Equippable", "Gun", "Firearm", "Weapon", "Revolver", "Pistol", "Rifle", "Shotgun", "ArmAnimator", "ArmController", "Holdable", "FilledPackaging", "Throwable" }; try { Il2CppArrayBase<MonoBehaviour> val3 = Object.FindObjectsOfType<MonoBehaviour>(); if (val3 != null) { for (int m = 0; m < val3.Count; m++) { MonoBehaviour val4 = val3[m]; if ((Object)(object)val4 == (Object)null || !((Behaviour)val4).enabled || _disabledScripts.Contains(val4)) { continue; } string name2 = ((MemberInfo)((Object)val4).GetIl2CppType()).Name; string[] array5 = array4; foreach (string value2 in array5) { if (name2.Contains(value2, StringComparison.OrdinalIgnoreCase)) { ((Behaviour)val4).enabled = false; _disabledScripts.Add(val4); break; } } } } } catch { } MelonLogger.Msg($"[AutoDistributor] Disabled {_disabledScripts.Count} scripts"); return; } foreach (MonoBehaviour disabledScript in _disabledScripts) { if ((Object)(object)disabledScript != (Object)null) { ((Behaviour)disabledScript).enabled = true; } } _disabledScripts.Clear(); } catch (Exception ex) { MelonLogger.Warning("[AutoDistributor] ToggleControl: " + ex.Message); } } private void Status(string m) { _statusMsg = m; _statusTime = Time.realtimeSinceStartup; MelonLogger.Msg("[AutoDistributor] " + m); } private void InitStyles() { //IL_0022: 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_002f: 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_0045: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00e4: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_0128: Expected O, but got Unknown //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: 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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Expected O, but got Unknown //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Expected O, but got Unknown //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Expected O, but got Unknown //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Expected O, but got Unknown //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Expected O, but got Unknown //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Expected O, but got Unknown //IL_038e: Unknown result type (might be due to invalid IL or missing references) if (!_stylesInit) { _stylesInit = true; _sEmpty = new GUIStyle(GUI.skin.box) { alignment = (TextAnchor)4, fontSize = 11, wordWrap = true }; _sEmpty.normal.textColor = new Color(0.5f, 0.5f, 0.5f); _sFilled = new GUIStyle(GUI.skin.box) { alignment = (TextAnchor)4, fontSize = 11, wordWrap = true, fontStyle = (FontStyle)1 }; _sFilled.normal.textColor = Color.white; _sHeader = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 14, fontStyle = (FontStyle)1 }; _sHeader.normal.textColor = Color.white; _sStatus = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 11, fontStyle = (FontStyle)2 }; _sStatus.normal.textColor = Color.yellow; _sBtn = new GUIStyle(GUI.skin.button) { fontSize = 15, fontStyle = (FontStyle)1 }; _sHotbar = new GUIStyle(GUI.skin.box) { alignment = (TextAnchor)4, fontSize = 10, wordWrap = true }; _sHotbar.normal.textColor = new Color(0.4f, 0.4f, 0.4f); _sHotbarFill = new GUIStyle(GUI.skin.button) { alignment = (TextAnchor)4, fontSize = 10, wordWrap = true }; _sHotbarFill.normal.textColor = new Color(0.9f, 0.9f, 0.3f); _sDone = new GUIStyle(GUI.skin.button) { fontSize = 16, fontStyle = (FontStyle)1 }; _sDone.normal.textColor = new Color(0.3f, 0.85f, 1f); _sPkgBaggie = new GUIStyle(GUI.skin.button) { alignment = (TextAnchor)4, fontSize = 10, wordWrap = true }; _sPkgBaggie.normal.textColor = new Color(0.4f, 1f, 0.4f); _sPkgJar = new GUIStyle(GUI.skin.button) { alignment = (TextAnchor)4, fontSize = 10, wordWrap = true }; _sPkgJar.normal.textColor = new Color(0.3f, 0.85f, 1f); _sPkgBrick = new GUIStyle(GUI.skin.button) { alignment = (TextAnchor)4, fontSize = 10, wordWrap = true }; _sPkgBrick.normal.textColor = new Color(1f, 0.6f, 0.2f); _sSliderLabel = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 11 }; _sSliderLabel.normal.textColor = new Color(0.6f, 0.6f, 0.6f); } } public override void OnGUI() { //IL_002e: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //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) if (_menuOpen) { InitStyles(); GUI.color = new Color(0f, 0f, 0f, 0.5f); GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; _windowRect = GUI.Window(987654, _windowRect, WindowFunction.op_Implicit((Action<int>)DrawWindow), "Auto Distributor v1.1.6"); HandleWindowResize(); } } private void HandleWindowResize() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Invalid comparison between Unknown and I4 //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Invalid comparison between Unknown and I4 //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Invalid comparison between Unknown and I4 //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) float num = 20f; Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).x + ((Rect)(ref _windowRect)).width - num, ((Rect)(ref _windowRect)).y + ((Rect)(ref _windowRect)).height - num, num, num); GUI.color = new Color(1f, 1f, 1f, 0.5f); GUI.Label(val, "◢", new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 14 }); GUI.color = Color.white; Event current = Event.current; if ((int)current.type == 0 && ((Rect)(ref val)).Contains(current.mousePosition)) { _isResizing = true; current.Use(); } if (_isResizing) { if ((int)current.type == 3 || (int)current.type == 2) { float num2 = current.mousePosition.x - ((Rect)(ref _windowRect)).x + 10f; float num3 = current.mousePosition.y - ((Rect)(ref _windowRect)).y + 10f; num2 = Mathf.Clamp(num2, 750f, 1400f); num3 = Mathf.Clamp(num3, 500f, 1000f); ((Rect)(ref _windowRect)).width = num2; ((Rect)(ref _windowRect)).height = num3; current.Use(); } if ((int)current.type == 1) { _isResizing = false; current.Use(); } } } private void DrawWindow(int id) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0489: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0686: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_06cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Expected O, but got Unknown //IL_0710: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_07aa: Unknown result type (might be due to invalid IL or missing references) //IL_08ff: Unknown result type (might be due to invalid IL or missing references) //IL_0913: Unknown result type (might be due to invalid IL or missing references) //IL_0918: Unknown result type (might be due to invalid IL or missing references) //IL_0920: Unknown result type (might be due to invalid IL or missing references) //IL_093a: Unknown result type (might be due to invalid IL or missing references) //IL_094a: Expected O, but got Unknown //IL_0848: Unknown result type (might be due to invalid IL or missing references) //IL_0871: Unknown result type (might be due to invalid IL or missing references) //IL_08a6: Unknown result type (might be due to invalid IL or missing references) float width = ((Rect)(ref _windowRect)).width; float height = ((Rect)(ref _windowRect)).height; GUI.DragWindow(new Rect(0f, 0f, width - 20f, 22f)); float num = 28f; GUI.Label(new Rect(10f, num, 430f, 20f), "Distribution Slots (click to return)", _sHeader); num += 24f; float num2 = Math.Min(width * 0.58f, 440f); float num3 = (num2 - 30f) / 5f; float num4 = num3 * 0.85f; int num5 = 0; for (int i = 0; i < 2; i++) { for (int j = 0; j < 5; j++) { DrawDistSlot(num5, 15f + (float)j * (num3 + 6f), num, num3, num4); num5++; } num += num4 + 6f; } float num6 = Math.Max(num2 + 20f, width * 0.6f); float num7 = width - num6 - 20f; GUI.Box(new Rect(num6, 28f, num7, 170f), ""); GUI.Label(new Rect(num6, 30f, num7, 20f), "Hired Dealers", _sHeader); _dealerScrollPos = GUI.BeginScrollView(new Rect(num6 + 5f, 54f, num7 - 10f, 110f), _dealerScrollPos, new Rect(0f, 0f, num7 - 30f, (float)Math.Max(110, _dealers.Count * 24 + 5))); if (_dealers.Count == 0) { GUI.Label(new Rect(5f, 5f, num7 - 40f, 25f), "No hired dealers found"); } else { for (int k = 0; k < _dealers.Count; k++) { float num8 = 5 + k * 24; DealerInfo dealerInfo = _dealers[k]; GUI.backgroundColor = (Color)(dealerInfo.Enabled ? new Color(0.3f, 0.8f, 0.3f) : Color.gray); if (GUI.Button(new Rect(5f, num8, 22f, 20f), "✓")) { dealerInfo.Enabled = true; } GUI.backgroundColor = (Color)((!dealerInfo.Enabled) ? new Color(0.9f, 0.3f, 0.3f) : Color.gray); if (GUI.Button(new Rect(30f, num8, 22f, 20f), "X")) { dealerInfo.Enabled = false; } GUI.backgroundColor = Color.white; GUIStyle val = new GUIStyle(GUI.skin.label); val.normal.textColor = (dealerInfo.Enabled ? new Color(0.4f, 1f, 0.4f) : new Color(1f, 0.4f, 0.4f)); GUI.Label(new Rect(58f, num8, num7 - 80f, 20f), dealerInfo.FullName, val); } } GUI.EndScrollView(); if (GUI.Button(new Rect(num6 + 5f, 170f, num7 - 10f, 25f), "Refresh")) { _dealers = GameBridge.GetRecruitedDealers(); _hotbarSlots = GameBridge.ReadPlayerHotbar(); _distResults.Clear(); Status($"{_dealers.Count} dealers, {_hotbarSlots.Length} slots"); } num += 8f; float num9 = width - 200f; float num10 = (width - num9) / 2f; int num11 = (int)_maxPerDealer; string text = ((num11 == 0) ? "Max per dealer: No Limit" : $"Max per dealer: {num11}"); GUI.Label(new Rect(num10, num, num9, 20f), text); num += 18f; _maxPerDealer = GUI.HorizontalSlider(new Rect(num10, num, num9, 20f), _maxPerDealer, 0f, 1000f); _maxPerDealer = Mathf.Round(_maxPerDealer / 10f) * 10f; num += 16f; GUI.Label(new Rect(num10, num, num9, 18f), "Max units of each product per dealer. 0 = no limit (distribute evenly)", _sSliderLabel); num += 20f; num += 10f; GUI.Label(new Rect(10f, num, width - 20f, 20f), "Your Hotbar (click to add)", _sHeader); num += 24f; if (_hotbarSlots.Length == 0) { GUI.Label(new Rect(20f, num, 400f, 25f), "Could not read hotbar – check console"); num += 28f; } else { int num12 = Math.Min(_hotbarSlots.Length, 20); int num13 = 5; float num14 = Math.Min(90f, (width - 80f) / (float)num13 - 6f); float num15 = num14 * 0.75f; float num16 = 6f; float num17 = (float)num13 * (num14 + num16); float num18 = (width - num17) / 2f; for (int l = 0; l < num12; l++) { int num19 = l / num13; int num20 = l % num13; DrawHotbarSlot(l, num18 + (float)num20 * (num14 + num16), num + (float)num19 * (num15 + num16), num14, num15); } int num21 = (num12 + num13 - 1) / num13; num += (float)num21 * (num15 + num16) + 4f; } num += 8f; float num22 = Math.Max(num, 440f); float num23 = Math.Min(420f, width * 0.55f); if (GUI.Button(new Rect(20f, num22, num23, 42f), "DISTRIBUTE", _sBtn)) { RunDistribution(); } if (GUI.Button(new Rect(num23 * 0.4f + 30f, num22 + 50f, num23 * 0.7f, 40f), "DONE", _sDone)) { _menuOpen = false; Close(); } if (GUI.Button(new Rect(20f, num22 + 50f, num23 * 0.35f, 40f), "Clear Slots")) { for (int m = 0; m < _distSlots.Length; m++) { _distSlots[m] = null; } _hotbarSlots = GameBridge.ReadPlayerHotbar(); Status("Slots cleared"); } int value = _distSlots.Count((DistSlot s) => s != null); GUI.Label(new Rect(width - 150f, num22 + 95f, 130f, 20f), $"Slots: {value}/10"); float num24 = num22 + 120f; if (_distResults.Count > 0) { float num25 = 22f; float num26 = 26f; float num27 = 8f; float num28 = num26 + (float)_distResults.Count * num25 + num27; GUI.Box(new Rect(10f, num24, width - 20f, num28), ""); GUI.Label(new Rect(10f, num24 + 2f, width - 20f, 22f), "Last Distribution", _sHeader); for (int n = 0; n < _distResults.Count; n++) { GUI.Label(new Rect(18f, num24 + num26 + (float)n * num25, width - 40f, num25), _distResults[n]); } num24 += num28 + 8f; } Rect val2 = new Rect(width - 25f, height - 25f, 20f, 20f); GUIStyle val3 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4 }; val3.normal.textColor = new Color(1f, 1f, 1f, 0.6f); GUI.Label(val2, "◢", val3); float num29 = num24 + 8f; if (((Rect)(ref _windowRect)).height < num29) { ((Rect)(ref _windowRect)).height = num29; } } private void DrawDistSlot(int i, float x, float y, float w = 80f, float h = 72f) { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) DistSlot distSlot = _distSlots[i]; Rect val = default(Rect); ((Rect)(ref val))..ctor(x, y, w, h); if (distSlot == null) { GUI.Button(val, $"Slot {i + 1}\n(empty)", _sEmpty); return; } string value = BuildInfoLine(distSlot.Packaging, distSlot.Quality); string text = $"{distSlot.DisplayName}\n{value} x{distSlot.Count}"; GUIStyle packagingStyle = GetPackagingStyle(distSlot.Packaging); Color textColor = packagingStyle.normal.textColor; _sFilled.normal.textColor = textColor; if (GUI.Button(val, text, _sFilled)) { _distSlots[i] = null; _sFilled.normal.textColor = Color.white; _hotbarSlots = GameBridge.ReadPlayerHotbar(); Status("Returned " + distSlot.DisplayName); } _sFilled.normal.textColor = Color.white; } private void DrawHotbarSlot(int i, float x, float y, float w, float h) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) if (i >= _hotbarSlots.Length) { return; } HotbarSlotInfo hotbarSlotInfo = _hotbarSlots[i]; Rect val = default(Rect); ((Rect)(ref val))..ctor(x, y, w, h); if (hotbarSlotInfo == null || string.IsNullOrEmpty(hotbarSlotInfo.DisplayName)) { GUI.Box(val, $"{i + 1}\n(empty)", _sHotbar); return; } int num = 0; DistSlot[] distSlots = _distSlots; foreach (DistSlot distSlot in distSlots) { if (distSlot != null && distSlot.HotbarIndex == i) { num += distSlot.Count; } } int num2 = hotbarSlotInfo.Count - num; string text = BuildInfoLine(hotbarSlotInfo.Packaging, hotbarSlotInfo.Quality); string text2 = ((num2 > 0) ? $"{hotbarSlotInfo.DisplayName}\n{text} x{num2}" : (hotbarSlotInfo.DisplayName + "\n" + text + " (moved)")); GUIStyle val2 = ((num2 <= 0) ? _sHotbar : GetPackagingStyle(hotbarSlotInfo.Packaging)); if (GUI.Button(val, text2, val2) && num2 > 0) { int num3 = Array.FindIndex(_distSlots, (DistSlot sl) => sl == null); if (num3 >= 0) { _distSlots[num3] = new DistSlot { DisplayName = hotbarSlotInfo.DisplayName, ProductID = (hotbarSlotInfo.ProductID ?? hotbarSlotInfo.DisplayName), Packaging = hotbarSlotInfo.Packaging, Quality = hotbarSlotInfo.Quality, Count = num2, HotbarIndex = i, GameSlotRef = hotbarSlotInfo.GameSlotRef }; Status($"Added {num2}x {hotbarSlotInfo.DisplayName}{(string.IsNullOrEmpty(hotbarSlotInfo.Packaging) ? "" : (" (" + hotbarSlotInfo.Packaging + ")"))}"); } else { Status("All 10 slots full!"); } } } private string BuildInfoLine(string packaging, string quality) { string text = (string.IsNullOrEmpty(packaging) ? "" : ("(" + packaging + ")")); string text2 = (string.IsNullOrEmpty(quality) ? "" : quality); return (text + " " + text2).Trim(); } private GUIStyle GetPackagingStyle(string packaging) { if (string.IsNullOrEmpty(packaging)) { return _sHotbarFill; } string text = packaging.ToLower(); if (text.Contains("baggie") || text.Contains("bag")) { return _sPkgBaggie; } if (text.Contains("jar")) { return _sPkgJar; } if (text.Contains("brick")) { return _sPkgBrick; } return _sHotbarFill; } private void RunDistribution() { _distResults.Clear(); List<DealerInfo> enabledDealers = _dealers.Where((DealerInfo d) => d.Enabled).ToList(); List<DealerInfo> list = _dealers.Where((DealerInfo d) => !d.Enabled).ToList(); if (enabledDealers.Count == 0) { foreach (DealerInfo dealer in _dealers) { _distResults.Add(dealer.FullName + ": Distribution Disabled"); } Status("No dealers enabled for distribution!"); return; } List<DistSlot> list2 = _distSlots.Where((DistSlot s) => s != null && s.Count > 0).ToList(); if (list2.Count == 0) { Status("No products in slots!"); return; } List<DistSlot> list3 = list2.Where((DistSlot s) => !string.IsNullOrEmpty(s.Packaging)).ToList(); List<DistSlot> list4 = list2.Where((DistSlot s) => string.IsNullOrEmpty(s.Packaging)).ToList(); if (list4.Count > 0) { string text = string.Join(", ", list4.Select((DistSlot s) => s.DisplayName)); MelonLogger.Msg("[AutoDistributor] Skipping non-product items: " + text); } if (list3.Count == 0) { Status("No distributable products in slots!"); return; } int count = enabledDealers.Count; Dictionary<string, Dictionary<string, int>> dictionary = new Dictionary<string, Dictionary<string, int>>(); Dictionary<string, bool> dictionary2 = new Dictionary<string, bool>(); foreach (DealerInfo item in enabledDealers) { dictionary[item.FullName] = new Dictionary<string, int>(); dictionary2[item.FullName] = false; } Dictionary<string, int> dictionary3 = new Dictionary<string, int>(); Dictionary<string, List<DistSlot>> dictionary4 = new Dictionary<string, List<DistSlot>>(); foreach (DistSlot item2 in list3) { string value = item2.ProductID ?? item2.DisplayName; string value2 = item2.Packaging ?? ""; string value3 = item2.Quality ?? ""; string key = $"{value}|{value2}|{value3}"; if (!dictionary4.ContainsKey(key)) { dictionary4[key] = new List<DistSlot>(); } dictionary4[key].Add(item2); } Dictionary<string, int>[] array = new Dictionary<string, int>[count]; for (int i = 0; i < count; i++) { array[i] = GameBridge.ReadDealerInventory(enabledDealers[i]); MelonLogger.Msg($"[AutoDistributor] {enabledDealers[i].FullName} inventory: {array[i].Count} product types"); } Dictionary<string, int[]> dictionary5 = new Dictionary<string, int[]>(); foreach (KeyValuePair<string, List<DistSlot>> item3 in dictionary4) { string key2 = item3.Key; List<DistSlot> value4 = item3.Value; string text2 = (key2.Contains('|') ? key2.Substring(0, key2.IndexOf('|')) : key2); string displayName = value4[0].DisplayName; string packaging = value4[0].Packaging; string quality = value4[0].Quality; string text3 = BuildInfoLine(packaging, quality); string text4 = (string.IsNullOrEmpty(text3) ? displayName : (displayName + " " + text3)); int distMult = GameBridge.GetPackagingMultiplier(packaging); int num = value4.Sum((DistSlot s) => s.Count); int num2 = num * distMult; int[] existing = new int[count]; if (!dictionary5.ContainsKey(text2)) { dictionary5[text2] = new int[count]; } for (int j = 0; j < count; j++) { array[j].TryGetValue(text2, out existing[j]); existing[j] += dictionary5[text2][j]; } int maxExisting = existing.Max(); MelonLogger.Msg($"[AutoDistributor] Product: {text4} ({text2})"); MelonLogger.Msg($"[AutoDistributor] Available: {num} pkgs ({num2} units), Existing units: [{string.Join(", ", existing)}], Max: {maxExisting}"); int num3 = maxExisting; int sliderLimit = (int)_maxPerDealer; bool usingSliderLimit = sliderLimit > 0; if (usingSliderLimit) { num3 = sliderLimit; } int[] array2 = new int[count]; int num4 = 0; int num5 = Enumerable.Range(0, count).Count((int d) => existing[d] < maxExisting); if ((num < num5 || (num <= count && distMult > 1 && num5 > 0)) && num5 > 0) { MelonLogger.Msg($"[AutoDistributor] Using package-based balancing ({num} packages, {num5} dealers need balance)"); } else if (num5 > 0) { int[] currentLevel2 = new int[count]; for (int k = 0; k < count; k++) { currentLevel2[k] = existing[k]; } int num6 = num2; while (num6 > 0) { int minLevel2 = currentLevel2.Min(); if (minLevel2 >= maxExisting) { break; } List<int> list5 = (from d in Enumerable.Range(0, count) where currentLevel2[d] == minLevel2 select d).ToList(); int num7 = maxExisting; for (int l = 0; l < count; l++) { if (currentLevel2[l] > minLevel2 && currentLevel2[l] < num7) { num7 = currentLevel2[l]; } } int num8 = num7 - minLevel2; int num9 = num8 * list5.Count; if (num9 <= num6) { foreach (int item4 in list5) { array2[item4] += num8; currentLevel2[item4] = num7; num4 += num8; } num6 -= num9; continue; } while (num6 > 0) { foreach (int item5 in list5) { if (num6 <= 0) { break; } array2[item5]++; currentLevel2[item5]++; num4++; num6--; } } } if (num4 > 0) { bool flag = currentLevel2.Min() >= maxExisting; MelonLogger.Msg($"[AutoDistributor] Phase 1: {(flag ? "Full" : "Partial")} balance, used {num4} units"); } } int num10 = num2 - num4; if (num10 > 0) { int[] currentLevel = new int[count]; for (int m = 0; m < count; m++) { currentLevel[m] = existing[m] + array2[m]; } int num11 = 0; while (num10 > 0) { List<int> list6 = new List<int>(); for (int n = 0; n < count; n++) { if (usingSliderLimit) { if (currentLevel[n] < sliderLimit) { list6.Add(n); } } else { list6.Add(n); } } if (list6.Count == 0) { break; } int minLevel = list6.Min((int d) => currentLevel[d]); List<int> list7 = list6.Where((int d) => currentLevel[d] == minLevel).ToList(); int num12 = minLevel + num10; if (usingSliderLimit) { num12 = sliderLimit; } foreach (int item6 in list6) { if (currentLevel[item6] > minLevel && currentLevel[item6] < num12) { num12 = currentLevel[item6]; } } int num13 = num12 - minLevel; if (num13 <= 0 || list7.Count == list6.Count) { int num14 = num10 / list6.Count; int num15 = num10 % list6.Count; for (int num16 = 0; num16 < list6.Count; num16++) { int num17 = list6[num16]; int num18 = num14 + ((num16 < num15) ? 1 : 0); if (usingSliderLimit) { int val = sliderLimit - currentLevel[num17]; num18 = Math.Min(num18, val); } array2[num17] += num18; currentLevel[num17] += num18; num11 += num18; num10 -= num18; } break; } int num19 = num13 * list7.Count; if (num19 <= num10) { foreach (int item7 in list7) { array2[item7] += num13; currentLevel[item7] = num12; num11 += num13; } num10 -= num19; continue; } while (num10 > 0) { foreach (int item8 in list7) { if (num10 <= 0) { break; } if (!usingSliderLimit || currentLevel[item8] < sliderLimit) { array2[item8]++; currentLevel[item8]++; num11++; num10--; } } if (num10 > 0) { list6 = list6.Where((int d) => !usingSliderLimit || currentLevel[d] < sliderLimit).ToList(); if (list6.Count == 0) { break; } minLevel = list6.Min((int d) => currentLevel[d]); list7 = list6.Where((int d) => currentLevel[d] == minLevel).ToList(); } } } if (num11 > 0) { MelonLogger.Msg($"[AutoDistributor] Phase 2: Distributed {num11} remaining units to eligible dealers"); } if (num10 > 0 && usingSliderLimit) { MelonLogger.Msg($"[AutoDistributor] Phase 2: {num10} units not distributed (all dealers at slider limit {sliderLimit})"); } } int[] toGive = new int[count]; int num20 = 0; for (int num21 = 0; num21 < count; num21++) { toGive[num21] = array2[num21] / distMult; num20 += toGive[num21]; } int num22 = num - num20; if (num22 > 0) { MelonLogger.Msg($"[AutoDistributor] Leftover packages to distribute: {num22}"); while (num22 > 0) { int[] array3 = (from d in Enumerable.Range(0, count) orderby existing[d] + toGive[d] * distMult select d).ToArray(); bool flag2 = false; int[] array4 = array3; int num23 = 0; while (num23 < array4.Length) { int num24 = array4[num23]; if (usingSliderLimit) { int num25 = existing[num24] + toGive[num24] * distMult; int num26 = num25 + distMult; if (num26 > sliderLimit) { num23++; continue; } } toGive[num24]++; num22--; flag2 = true; break; } if (!flag2) { MelonLogger.Msg($"[AutoDistributor] {num22} packages remaining (all dealers at slider limit {sliderLimit})"); break; } } } MelonLogger.Msg("[AutoDistributor] Distribution (packages): [" + string.Join(", ", from d in Enumerable.Range(0, count) select $"{enabledDealers[d].FullName}={toGive[d]}") + "]"); DistSlot slot = value4[0]; int num27 = 0; for (int num28 = 0; num28 < count; num28++) { if (toGive[num28] <= 0) { continue; } int dealerCapacity = GameBridge.GetDealerCapacity(enabledDealers[num28], slot); if (dealerCapacity <= 0) { MelonLogger.Warning($"[AutoDistributor] {enabledDealers[num28].FullName} has no room for {displayName} (all slots full)"); dictionary2[enabledDealers[num28].FullName] = true; toGive[num28] = 0; continue; } if (toGive[num28] > dealerCapacity) { MelonLogger.Msg($"[AutoDistributor] Clamped {enabledDealers[num28].FullName}: {toGive[num28]}->{dealerCapacity} {displayName}"); toGive[num28] = dealerCapacity; } if (GameBridge.GiveItemToDealer(enabledDealers[num28], slot, toGive[num28])) { num27 += toGive[num28]; dictionary5[text2][num28] += toGive[num28] * distMult; if (dictionary3.ContainsKey(text4)) { dictionary3[text4] += toGive[num28]; } else { dictionary3[text4] = toGive[num28]; } Dictionary<string, int> dictionary6 = dictionary[enabledDealers[num28].FullName]; if (dictionary6.ContainsKey(text4)) { dictionary6[text4] += toGive[num28]; } else { dictionary6[text4] = toGive[num28]; } } } int num29 = num - num27; if (num29 > 0) { MelonLogger.Msg($"[AutoDistributor] {num29}x {displayName} not distributed (dealers full or at limit)"); } if (num27 > 0) { foreach (DistSlot item9 in value4) { if (num27 <= 0) { break; } int num30 = Math.Min(item9.Count, num27); if (num30 > 0) { GameBridge.RemoveFromPlayerPartial(item9, num30); num27 -= num30; item9.Count -= num30; } } MelonLogger.Msg("[AutoDistributor] Removed distributed " + displayName); } for (int num31 = 0; num31 < _distSlots.Length; num31++) { if (_distSlots[num31] != null && _distSlots[num31].Count <= 0) { _distSlots[num31] = null; } } } foreach (DealerInfo item10 in enabledDealers) { Dictionary<string, int> dictionary7 = dictionary[item10.FullName]; bool flag3 = dictionary2[item10.FullName]; if (dictionary7.Count == 0) { if (flag3) { _distResults.Add(item10.FullName + ": nothing (Inventory Full)"); } else { _distResults.Add(item10.FullName + ": nothing"); } continue; } string text5 = string.Join(", ", dictionary7.Select((KeyValuePair<string, int> kv) => $"{kv.Value}x {kv.Key}")); if (flag3) { _distResults.Add(item10.FullName + ": " + text5 + " (some skipped - Inventory Full)"); } else { _distResults.Add(item10.FullName + ": " + text5); } } foreach (DealerInfo item11 in list) { _distResults.Add(item11.FullName + ": Distribution Disabled"); } if (list4.Count > 0) { string text6 = string.Join(", ", list4.Select((DistSlot s) => s.DisplayName)); _distResults.Add("--- Skipped (not products): " + text6); } for (int num32 = 0; num32 < _distSlots.Length; num32++) { if (_distSlots[num32] != null && !string.IsNullOrEmpty(_distSlots[num32].Packaging)) { _distSlots[num32] = null; } } _hotbarSlots = GameBridge.ReadPlayerHotbar(); string value5 = string.Join(", ", dictionary3.Select((KeyValuePair<string, int> kv) => $"{kv.Value}x {kv.Key}")); Status($"Distributed to {count} dealers: {value5}"); } } public class DistSlot { public string DisplayName; public string ProductID; public string Packaging; public string Quality; public int Count; public int HotbarIndex; public object GameSlotRef; } public class HotbarSlotInfo { public string DisplayName; public string ProductID; public string Packaging; public string Quality; public int Count; public int SlotIndex; public object GameSlotRef; } public class DealerInfo { public string FullName; public object DealerObj; public bool Enabled = true; } public static class GameBridge { private static Type _dealerProxyType; private static Type _playerInvProxyType; private static Type _dealerIl2Type; private static bool _typesSearched; private static void EnsureTypes() { if (_typesSearched) { return; } _typesSearched = true; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { string text = assembly.GetName().Name ?? ""; if (!text.Contains("Il2Cpp") && !text.Contains("Assembly")) { continue; } try { Type[] types = assembly.GetTypes(); foreach (Type type in types) { string text2 = type.FullName ?? ""; if (text2 == "Il2CppScheduleOne.Economy.Dealer") { _dealerProxyType = type; MelonLogger.Msg("[AutoDistributor] Dealer proxy: " + text2); try { _dealerIl2Type = Il2CppType.From(type); } catch { } } if (text2 == "Il2CppScheduleOne.PlayerScripts.PlayerInventory") { _playerInvProxyType = type; MelonLogger.Msg("[AutoDistributor] PlayerInv proxy: " + text2); } } } catch { } } if (_dealerProxyType == null) { MelonLogger.Warning("[AutoDistributor] Dealer proxy NOT found"); } if (_playerInvProxyType == null) { MelonLogger.Warning("[AutoDistributor] PlayerInventory proxy NOT found"); } } public static List<DealerInfo> GetRecruitedDealers() { EnsureTypes(); List<DealerInfo> list = new List<DealerInfo>(); if (_dealerIl2Type == (Type)null) { MelonLogger.Warning("[AutoDistributor] No dealer IL2CPP type"); return list; } try { Il2CppReferenceArray<Object> val = Object.FindObjectsOfType(_dealerIl2Type); int num = ((Il2CppArrayBase<Object>)(object)val)?.Count ?? 0; MelonLogger.Msg($"[AutoDistributor] Dealers in world: {num}"); for (int i = 0; i < num; i++) { Object val2 = ((Il2CppArrayBase<Object>)(object)val)[i]; if (val2 == (Object)null) { continue; } string text = val2.name ?? ""; string text2 = ((Object)val2).GetIl2CppType().FullName ?? ""; if (text.Contains("Cartel", StringComparison.OrdinalIgnoreCase) || text2.Contains("Cartel", StringComparison.OrdinalIgnoreCase)) { continue; } object obj = CastToProxy(val2, _dealerProxyType); if (obj != null) { bool propBool = GetPropBool(obj, "IsRecruited"); string dealerName = GetDealerName(obj); if (!propBool) { MelonLogger.Msg("[AutoDistributor] Skip not-recruited: " + dealerName); continue; } list.Add(new DealerInfo { FullName = dealerName, DealerObj = obj }); MelonLogger.Msg("[AutoDistributor] Recruited: " + dealerName); } } } catch (Exception value) { MelonLogger.Error($"[AutoDistributor] GetDealers: {value}"); } MelonLogger.Msg($"[AutoDistributor] Recruited total: {list.Count}"); return list; } public static HotbarSlotInfo[] ReadPlayerHotbar() { EnsureTypes(); List<HotbarSlotInfo> list = new List<HotbarSlotInfo>(); try { object obj = FindPlayerInventory(); if (obj == null) { MelonLogger.Warning("[AutoDistributor] PlayerInventory not found"); return list.ToArray(); } Type type = obj.GetType(); string[] array = new string[12] { "hotbarSlots", "HotbarSlots", "Hotbar", "ItemSlots", "itemSlots", "Slots", "slots", "Items", "items", "HotBarSlots", "_hotbarSlots", "_HotbarSlots" }; object obj2 = null; string text = null; string[] array2 = array; foreach (string text2 in array2) { obj2 = TryGetProp(obj, text2); if (obj2 != null) { text = text2; break; } obj2 = TryGetField(obj, text2); if (obj2 != null) { text = text2 + "(field)"; break; } } if (obj2 != null) { list = ReadSlotCollection(obj2); } if (list.Count == 0) { MelonLogger.Warning("[AutoDistributor] Could not read hotbar slots"); } } catch (Exception value) { MelonLogger.Error($"[AutoDistributor] ReadHotbar: {value}"); } return list.ToArray(); } private static object FindPlayerInventory() { if (_playerInvProxyType != null) { try { Type val = Il2CppType.From(_playerInvProxyType); if (val != (Type)null) { Il2CppReferenceArray<Object> val2 = Object.FindObjectsOfType(val); if (val2 != null && ((Il2CppArrayBase<Object>)(object)val2).Count > 0) { Object raw = ((Il2CppArrayBase<Object>)(object)val2)[0]; object obj = CastToProxy(raw, _playerInvProxyType); if (obj != null) { return obj; } } } } catch (Exception ex) { MelonLogger.Msg("[AutoDistributor] FOT PlayerInv: " + ex.Message); } } GameObject val3 = GameObject.Find("Player_Local(Clone)") ?? GameObject.Find("Player_Local") ?? GameObject.Find("Player(Clone)"); if ((Object)(object)val3 == (Object)null) { return null; } Il2CppArrayBase<Component> componentsInChildren = val3.GetComponentsInChildren<Component>(); if (componentsInChildren == null) { return null; } for (int i = 0; i < componentsInChildren.Count; i++) { Component val4 = componentsInChildren[i]; if ((Object)(object)val4 == (Object)null) { continue; } string text = ((Object)val4).GetIl2CppType().FullName ?? ""; if (!text.Contains("PlayerInventory")) { continue; } if (_playerInvProxyType != null) { object obj2 = CastToProxy((Object)(object)val4, _playerInvProxyType); if (obj2 != null) { return obj2; } } return val4; } return null; } private static List<HotbarSlotInfo> ReadSlotCollection(object collection) { List<HotbarSlotInfo> list = new List<HotbarSlotInfo>(); Type type = collection.GetType(); try { PropertyInfo propertyInfo = type.GetProperty("Count") ?? type.GetProperty("Length"); if (propertyInfo == null) { return list; } int val = (int)propertyInfo.GetValue(collection); PropertyInfo property = type.GetProperty("Item"); if (property == null) { return list; } for (int i = 0; i < Math.Min(val, 20); i++) { try { object value = property.GetValue(collection, new object[1] { i }); if (value == null) { list.Add(new HotbarSlotInfo { SlotIndex = i }); } else { HotbarSlotInfo hotbarSlotInfo = ReadSingleSlot(value, i); list.Add(hotbarSlotInfo ?? new HotbarSlotInfo { SlotIndex = i }); } } catch { list.Add(new HotbarSlotInfo { SlotIndex = i }); } } } catch (Exception ex) { MelonLogger.Msg("[AutoDistributor] ReadSlotCollection: " + ex.Message); } return list; } private static HotbarSlotInfo ReadSingleSlot(object slot, int index) { Type type = slot.GetType(); int num = 0; if ((TryGetProp(slot, "Quantity") ?? TryGetProp(slot, "quantity") ?? TryGetProp(slot, "Count")) is int num2) { num = num2; } object obj = TryGetProp(slot, "ItemInstance") ?? TryGetProp(slot, "StoredInstance") ?? TryGetProp(slot, "Item") ?? TryGetProp(slot, "item"); if (obj == null && num <= 0) { return null; } string text = null; if (obj != null) { object obj2 = TryGetProp(obj, "Definition") ?? TryGetProp(obj, "ItemDefinition") ?? TryGetProp(obj, "definition"); if (obj2 != null) { text = TryGetProp(obj2, "Name")?.ToString() ?? TryGetProp(obj2, "name")?.ToString() ?? TryGetProp(obj2, "DisplayName")?.ToString(); } if (text == null) { text = TryGetProp(obj, "Name")?.ToString() ?? TryGetProp(obj, "name")?.ToString() ?? TryGetProp(obj, "DisplayName")?.ToString() ?? TryGetProp(obj, "ItemName")?.ToString(); } if (text == null) { text = obj.ToString(); } } if (text == null && num <= 0) { return null; } if (num <= 0) { num = 1; } string text2 = null; if (obj != null) { text2 = TryGetProp(obj, "ID")?.ToString() ?? TryGetProp(obj, "id")?.ToString(); } string text3 = null; string quality = null; if (obj != null) { string text4 = TryGetProp(obj, "Category")?.ToString() ?? ""; if (text4.Contains("Product") || text4.Contains("Drug")) { Object val = (Object)((obj is Object) ? obj : null); if (val != null) { try { Type il2CppType = val.GetIl2CppType(); if (il2CppType != (Type)null) { PropertyInfo property = il2CppType.GetProperty("AppliedPackaging"); if (property != (PropertyInfo)null) { Object value = property.GetValue(val, (Il2CppReferenceArray<Object>)null); if (value != null) { text3 = TryGetProp(value, "Name")?.ToString() ?? value.ToString(); } } if (text3 == null) { FieldInfo field = il2CppType.GetField("PackagingID"); if (field != (FieldInfo)null) { Object value2 = field.GetValue(val); if (value2 != null) { text3 = value2.ToString(); } } } text3 = CleanPackagingName(text3); FieldInfo field2 = il2CppType.GetField("Quality"); if (field2 != (FieldInfo)null) { Object value3 = field2.GetValue(val); if (value3 != null) { quality = value3.ToString(); } } } } catch { } } } } return new HotbarSlotInfo { DisplayName = (text ?? "Item"), ProductID = (text2 ?? text ?? "unknown"), Packaging = text3, Quality = quality, Count = num, SlotIndex = index, GameSlotRef = slot }; } public static Dictionary<string, int> ReadDealerInventory(DealerInfo dealer) { Dictionary<string, int> dictionary = new Dictionary<string, int>(); try { object dealerObj = dealer.DealerObj; if (dealerObj == null) { return dictionary; } object obj = TryGetProp(dealerObj, "Inventory"); if (obj == null) { return dictionary; } object obj2 = TryGetProp(obj, "ItemSlots"); if (obj2 == null) { return dictionary; } Type type = obj2.GetType(); PropertyInfo property = type.GetProperty("Count"); PropertyInfo property2 = type.GetProperty("Item"); if (property == null || property2 == null) { return dictionary; } int num = (int)property.GetValue(obj2); for (int i = 0; i < num; i++) { try { object value = property2.GetValue(obj2, new object[1] { i }); if (value == null) { continue; } int num2 = 0; if (TryGetProp(value, "Quantity") is int num3) { num2 = num3; } if (num2 <= 0) { continue; } object obj3 = TryGetProp(value, "ItemInstance"); if (obj3 == null) { continue; } string text = TryGetProp(obj3, "ID")?.ToString() ?? TryGetProp(obj3, "id")?.ToString(); string text2 = TryGetProp(obj3, "Name")?.ToString(); if (string.IsNullOrEmpty(text)) { text = text2 ?? "unknown"; } int num4 = 1; try { Object val = (Object)((obj3 is Object) ? obj3 : null); if (val != null) { Type il2CppType = val.GetIl2CppType(); if (il2CppType != (Type)null) { string text3 = null; PropertyInfo property3 = il2CppType.GetProperty("AppliedPackaging"); if (property3 != (PropertyInfo)null) { Object value2 = property3.GetValue(val, (Il2CppReferenceArray<Object>)null); if (value2 != null) { text3 = TryGetProp(value2, "Name")?.ToString() ?? value2.ToString(); } } if (text3 == null) { FieldInfo field = il2CppType.GetField("PackagingID"); if (field != (FieldInfo)null) { Object value3 = field.GetValue(val); if (value3 != null) { text3 = value3.ToString(); } } } text3 = CleanPackagingName(text3); num4 = GetPackagingMultiplier(text3); } } } catch { } int num5 = num2 * num4; if (dictionary.ContainsKey(text)) { dictionary[text] += num5; } else { dictionary[text] = num5; } } catch { } } if (dictionary.Count > 0) { string text4 = string.Join(", ", dictionary.Select((KeyValuePair<string, int> kv) => $"{kv.Value}x {kv.Key}")); MelonLogger.Msg("[AutoDistributor] " + dealer.FullName + ": " + text4); } } catch (Exception ex) { MelonLogger.Warning("[AutoDistributor] ReadDealerInv: " + ex.Message); } return dictionary; } public static int GetPackagingMultiplier(string packaging) { if (string.IsNullOrEmpty(packaging)) { return 1; } string text = packaging.ToLowerInvariant(); if (text.Contains("brick")) { return 20; } if (text.Contains("jar")) { return 5; } return 1; } public static string CleanPackagingName(string raw) { if (string.IsNullOrEmpty(raw)) { return null; } string text = raw.ToLowerInvariant(); if (text.Contains("packagingdefiniti") || text.Contains("scheduleone")) { if (text.Contains("brick")) { return "Brick"; } if (text.Contains("jar")) { return "Jar"; } return "Baggie"; } if (raw.Length > 0) { return char.ToUpper(raw[0]) + raw.Substring(1).ToLower(); } return raw; } public static int GetDealerCapacity(DealerInfo dealer, DistSlot slot) { try { object dealerObj = dealer.DealerObj; if (dealerObj == null) { return int.MaxValue; } object gameSlotRef = slot.GameSlotRef; if (gameSlotRef == null) { return int.MaxValue; } object obj = TryGetProp(gameSlotRef, "ItemInstance") ?? TryGetProp(gameSlotRef, "StoredInstance"); if (obj == null) { return int.MaxValue; } object obj2 = TryGetProp(dealerObj, "Inventory"); if (obj2 == null) { return int.MaxValue; } MethodInfo method = obj2.GetType().GetMethod("GetCapacityForItem", BindingFlags.Instance | BindingFlags.Public); if (method == null) { return int.MaxValue; } return (int)method.Invoke(obj2, new object[1] { obj }); } catch { return int.MaxValue; } } public static bool GiveItemToDealer(DealerInfo dealer, DistSlot slot, int amount) { try { object dealerObj = dealer.DealerObj; if (dealerObj == null) { return false; } object gameSlotRef = slot.GameSlotRef; if (gameSlotRef == null) { MelonLogger.Warning("[AutoDistributor] No game ref"); return false; } object obj = TryGetProp(gameSlotRef, "ItemInstance") ?? TryGetProp(gameSlotRef, "StoredInstance") ?? TryGetProp(gameSlotRef, "Item"); if (obj == null) { MelonLogger.Warning("[AutoDistributor] No ItemInstance: " + slot.DisplayName); return false; } object obj2 = TryGetProp(dealerObj, "Inventory"); if (obj2 != null) { Type type = obj2.GetType(); MethodInfo method = type.GetMethod("GetCapacityForItem", BindingFlags.Instance | BindingFlags.Public); if (method != null) { try { int num = (int)method.Invoke(obj2, new object[1] { obj }); if (num <= 0) { MelonLogger.Warning($"[AutoDistributor] {dealer.FullName} is full for {slot.DisplayName}"); return false; } if (amount > num) { MelonLogger.Warning($"[AutoDistributor] {dealer.FullName} can only fit {num}/{amount} {slot.DisplayName}, clamping"); amount = num; } } catch { } } } Type type2 = obj.GetType(); MethodInfo method2 = type2.GetMethod("GetCopy", BindingFlags.Instance | BindingFlags.Public); if (method2 == null) { MelonLogger.Warning("[AutoDistributor] No GetCopy method"); return false; } object obj4 = method2.Invoke(obj, new object[1] { amount }); if (obj4 == null) { MelonLogger.Warning("[AutoDistributor] GetCopy returned null"); return false; } if (obj2 != null) { MethodInfo method3 = obj2.GetType().GetMethod("InsertItem", BindingFlags.Instance | BindingFlags.Public); if (method3 != null) { try { method3.Invoke(obj2, new object[2] { obj4, true }); MelonLogger.Msg($"[AutoDistributor] Inserted {amount}x {slot.DisplayName} -> {dealer.FullName}"); return true; } catch (Exception ex) { MelonLogger.Warning("[AutoDistributor] InsertItem: " + ex.Message); } } } Type type3 = dealerObj.GetType(); object obj5 = TryGetProp(dealerObj, "ItemSlots"); if (obj5 != null) { Type type4 = obj5.GetType(); PropertyInfo property = type4.GetProperty("Count"); PropertyInfo property2 = type4.GetProperty("Item"); if (property != null && property2 != null) { int num2 = (int)property.GetValue(obj5); int num3 = -1; for (int i = 0; i < num2; i++) { object value = property2.GetValue(obj5, new object[1] { i }); if (value != null) { object obj6 = TryGetProp(value, "ItemInstance"); int num4 = 0; if (TryGetProp(value, "Quantity") is int num5) { num4 = num5; } if (obj6 == null && num4 <= 0) { num3 = i; break; } } } if (num3 >= 0) { MethodInfo method4 = type3.GetMethod("SetStoredInstance_Internal", BindingFlags.Instance | BindingFlags.Public); if (method4 != null) { method4.Invoke(dealerObj, new object[3] { null, num3, obj4 }); MelonLogger.Msg($"[AutoDistributor] Fallback: {amount}x {slot.DisplayName} -> {dealer.FullName} slot {num3}"); return true; } } } } MelonLogger.Warning("[AutoDistributor] All approaches failed: " + dealer.FullName); return false; } catch (Exception value2) { MelonLogger.Error($"[AutoDistributor] GiveItem: {value2}"); return false; } } public static void RemoveFromPlayer(DistSlot slot) { try { object gameSlotRef = slot.GameSlotRef; if (gameSlotRef == null) { return; } Type type = gameSlotRef.GetType(); MethodInfo method = type.GetMethod("ClearStoredInstance", BindingFlags.Instance | BindingFlags.Public); if (method != null) { try { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 1) { method.Invoke(gameSlotRef, new object[1] { true }); } else { method.Invoke(gameSlotRef, null); } MelonLogger.Msg("[AutoDistributor] Cleared " + slot.DisplayName); return; } catch (Exception ex) { MelonLogger.Warning("[AutoDistributor] ClearStored: " + ex.Message); } } MethodInfo method2 = type.GetMethod("SetQuantity", BindingFlags.Instance | BindingFlags.Public); if (method2 != null) { try { ParameterInfo[] parameters2 = method2.GetParameters(); if (parameters2.Length == 2) { method2.Invoke(gameSlotRef, new object[2] { 0, true }); } else if (parameters2.Length == 1) { method2.Invoke(gameSlotRef, new object[1] { 0 }); } MelonLogger.Msg("[AutoDistributor] SetQty 0: " + slot.DisplayName); return; } catch (Exception ex2) { MelonLogger.Warning("[AutoDistributor] SetQty: " + ex2.Message); } } MelonLogger.Warning("[AutoDistributor] Could not remove " + slot.DisplayName); } catch (Exception ex3) { MelonLogger.Warning("[AutoDistributor] Remove: " + ex3.Message); } } public static void RemoveFromPlayerPartial(DistSlot slot, int amount) { try { object gameSlotRef = slot.GameSlotRef; if (gameSlotRef == null) { return; } if (amount >= slot.Count) { RemoveFromPlayer(slot); return; } Type type = gameSlotRef.GetType(); int count = slot.Count; int num = count - amount; if (num < 0) { num = 0; } MethodInfo method = type.GetMethod("SetQuantity", BindingFlags.Instance | BindingFlags.Public); if (method != null) { try { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 2) { method.Invoke(gameSlotRef, new object[2] { num, true }); } else if (parameters.Length == 1) { method.Invoke(gameSlotRef, new object[1] { num }); } return; } catch { } } MethodInfo method2 = type.GetMethod("ChangeQuantity", BindingFlags.Instance | BindingFlags.Public); if (method2 != null) { try { method2.Invoke(gameSlotRef, new object[1] { -amount }); return; } catch { } } MelonLogger.Warning("[AutoDistributor] Partial remove failed, clearing slot"); RemoveFromPlayer(slot); } catch (Exception ex) { MelonLogger.Warning("[AutoDistributor] RemovePartial: " + ex.Message); } } private static object CastToProxy(Object raw, Type proxyType) { if (raw == (Object)null || proxyType == null) { return null; } try { ConstructorInfo constructor = proxyType.GetConstructor(new Type[1] { typeof(IntPtr) }); if (constructor != null) { IntPtr pointer = ((Il2CppObjectBase)raw).Pointer; if (pointer != IntPtr.Zero) { return constructor.Invoke(new object[1] { pointer }); } } } catch (Exception ex) { MelonLogger.Msg("[AutoDistributor] Cast to " + proxyType.Name + ": " + ex.Message); } return null; } private static object TryGetProp(object obj, string name) { if (obj == null) { return null; } try { return obj.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)?.GetValue(obj); } catch { return null; } } private static object TryGetField(object obj, string name) { if (obj == null) { return null; } try { return obj.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)?.GetValue(obj); } catch { return null; } } private static bool GetPropBool(object obj, string name) { if (TryGetProp(obj, name) is bool result) { return result; } return false; } private static string GetDealerName(object dealer) { string[] array = new string[4] { "fullName", "FullName", "FirstName", "name" }; foreach (string name in array) { string text = TryGetProp(dealer, name)?.ToString(); if (!string.IsNullOrEmpty(text)) { return text; } } return "Unknown"; } } }