Decompiled source of MoreStations v1.0.0

MoreStations\MoreStations.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne.Management;
using Il2CppScheduleOne.UI.Management;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using MoreStations;
using MoreStations.Config;
using MoreStations.Patches;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(MoreStationsMod), "More Stations", "1.0.0", "brobb", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: AssemblyMetadata("NexusModID", "0")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("MoreStations")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MoreStations")]
[assembly: AssemblyTitle("MoreStations")]
[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 MoreStations
{
	public class MoreStationsMod : MelonMod
	{
		public override void OnInitializeMelon()
		{
			StationConfig.Initialize();
			StationLimits.Initialize();
			((MelonBase)this).LoggerInstance.Msg("More Stations initialized.");
		}
	}
}
namespace MoreStations.Patches
{
	public static class StationLimits
	{
		private class StationLimitPatches
		{
			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPostfix]
			private static void BotanistConfigurationCtor(BotanistConfiguration __instance)
			{
				ApplyMaxItems((__instance != null) ? __instance.Assigns : null, BotanistMax);
			}

			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPostfix]
			private static void ChemistConfigurationCtor(ChemistConfiguration __instance)
			{
				ApplyMaxItems((__instance != null) ? __instance.Stations : null, ChemistMax);
			}

			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPostfix]
			private static void CleanerConfigurationCtor(CleanerConfiguration __instance)
			{
				ApplyMaxItems((__instance != null) ? __instance.Bins : null, JanitorMax);
			}

			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPostfix]
			private static void PackagerConfigurationCtor(PackagerConfiguration __instance)
			{
				ApplyMaxItems((__instance != null) ? __instance.Stations : null, HandlerMax);
			}

			[HarmonyPatch(typeof(BotanistConfigPanel), "Bind")]
			[HarmonyPostfix]
			private static void BotanistPanelBind(BotanistConfigPanel __instance)
			{
				ApplyLimits((__instance != null) ? __instance.PotsUI : null, BotanistMax, 0f, 0f);
			}

			[HarmonyPatch(typeof(ChemistConfigPanel), "Bind")]
			[HarmonyPostfix]
			private static void ChemistPanelBind(ChemistConfigPanel __instance)
			{
				ApplyLimits((__instance != null) ? __instance.StationsUI : null, ChemistMax, 0f, 0f);
			}

			[HarmonyPatch(typeof(CleanerConfigPanel), "Bind")]
			[HarmonyPostfix]
			private static void CleanerPanelBind(CleanerConfigPanel __instance)
			{
				ApplyLimits((__instance != null) ? __instance.BinsUI : null, JanitorMax, 0f, 0f);
			}

			[HarmonyPatch(typeof(PackagerConfigPanel), "Bind")]
			[HarmonyPostfix]
			private static void PackagerPanelBind(PackagerConfigPanel __instance)
			{
				ApplyLimits((__instance != null) ? __instance.StationsUI : null, HandlerMax, HandlerListHeight, HandlerListOffset);
			}
		}

		private static bool _initialized;

		private static readonly Dictionary<int, float> ScrollOffsets = new Dictionary<int, float>();

		private static int JanitorMax => ClampMax(StationConfig.JanitorMaxStations.Value);

		private static int BotanistMax => ClampMax(StationConfig.BotanistMaxStations.Value);

		private static int ChemistMax => ClampMax(StationConfig.ChemistMaxStations.Value);

		private static int HandlerMax => ClampMax(StationConfig.HandlerMaxStations.Value);

		private static float HandlerListHeight => 100f;

		private static float HandlerListOffset => 100f;

		public static void Initialize()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (!_initialized)
			{
				new Harmony("MoreStations.StationLimits").PatchAll(typeof(StationLimitPatches));
				_initialized = true;
			}
		}

		private static int ClampMax(int value)
		{
			return Math.Max(1, value);
		}

		private static void ApplyMaxItems(ObjectListField field, int maxItems)
		{
			if (field != null)
			{
				field.MaxItems = maxItems;
			}
		}

		private static void ApplyMaxItems(List<ObjectListField> fields, int maxItems)
		{
			if (fields != null)
			{
				Enumerator<ObjectListField> enumerator = fields.GetEnumerator();
				while (enumerator.MoveNext())
				{
					ApplyMaxItems(enumerator.Current, maxItems);
				}
			}
		}

		private static Transform GetContents(ObjectListFieldUI listUi)
		{
			Transform transform = ((Component)listUi).transform;
			Transform val = transform.Find("Contents");
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			Transform val2 = transform.Find("ScrollArea");
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			return val2.Find("Contents");
		}

		private static void EnsureScrollable(ObjectListFieldUI listUi, float heightOverride, float verticalOffset)
		{
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)listUi == (Object)null)
			{
				return;
			}
			Transform transform = ((Component)listUi).transform;
			Transform val = transform.Find("ScrollArea");
			Transform contents = GetContents(listUi);
			if ((Object)(object)contents == (Object)null)
			{
				return;
			}
			RectTransform component = ((Component)contents).GetComponent<RectTransform>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			float viewportHeight = GetViewportHeight(listUi, component, heightOverride);
			int instanceID = ((Object)listUi).GetInstanceID();
			if ((Object)(object)val != (Object)null)
			{
				RectTransform component2 = ((Component)val).GetComponent<RectTransform>();
				ApplyVerticalOffset(component2, instanceID, verticalOffset);
				if ((Object)(object)component2 != (Object)null && viewportHeight > 0f)
				{
					component2.SetSizeWithCurrentAnchors((Axis)1, viewportHeight);
				}
				LayoutElement val2 = ((Component)val).GetComponent<LayoutElement>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)val).gameObject.AddComponent<LayoutElement>();
				}
				if (viewportHeight > 0f)
				{
					val2.preferredHeight = viewportHeight;
					val2.minHeight = viewportHeight;
				}
				ScrollRect component3 = ((Component)val).GetComponent<ScrollRect>();
				if ((Object)(object)component3 != (Object)null)
				{
					component3.content = component;
					component3.viewport = component2;
				}
				return;
			}
			GameObject val3 = new GameObject("ScrollArea");
			val3.AddComponent<RectTransform>();
			val3.AddComponent<RectMask2D>();
			ScrollRect obj = val3.AddComponent<ScrollRect>();
			val3.transform.SetParent(transform, false);
			RectTransform component4 = val3.GetComponent<RectTransform>();
			component4.anchorMin = component.anchorMin;
			component4.anchorMax = component.anchorMax;
			component4.pivot = component.pivot;
			component4.anchoredPosition = component.anchoredPosition;
			component4.sizeDelta = component.sizeDelta;
			((Transform)component4).localScale = ((Transform)component).localScale;
			((Transform)component4).localRotation = ((Transform)component).localRotation;
			ApplyVerticalOffset(component4, instanceID, verticalOffset);
			if (viewportHeight > 0f)
			{
				component4.SetSizeWithCurrentAnchors((Axis)1, viewportHeight);
			}
			LayoutElement val4 = val3.GetComponent<LayoutElement>();
			if ((Object)(object)val4 == (Object)null)
			{
				val4 = val3.AddComponent<LayoutElement>();
			}
			if (viewportHeight > 0f)
			{
				val4.preferredHeight = viewportHeight;
				val4.minHeight = viewportHeight;
			}
			val3.transform.SetSiblingIndex(contents.GetSiblingIndex());
			contents.SetParent(val3.transform, false);
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = Vector2.zero;
			ContentSizeFitter val5 = ((Component)component).GetComponent<ContentSizeFitter>();
			if ((Object)(object)val5 == (Object)null)
			{
				val5 = ((Component)component).gameObject.AddComponent<ContentSizeFitter>();
			}
			val5.horizontalFit = (FitMode)0;
			val5.verticalFit = (FitMode)2;
			obj.content = component;
			obj.horizontal = false;
			obj.vertical = true;
			obj.scrollSensitivity = 5f;
			obj.viewport = component4;
		}

		private static float GetViewportHeight(ObjectListFieldUI listUi, RectTransform contentsRect, float heightOverride)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)contentsRect == (Object)null)
			{
				return 0f;
			}
			if (heightOverride > 0f)
			{
				return heightOverride;
			}
			int valueOrDefault = ((listUi == null) ? null : ((Il2CppArrayBase<RectTransform>)(object)listUi.Entries)?.Length).GetValueOrDefault();
			Rect rect = contentsRect.rect;
			float height = ((Rect)(ref rect)).height;
			float num = 0f;
			if (valueOrDefault > 0)
			{
				RectTransform val = ((Il2CppArrayBase<RectTransform>)(object)listUi.Entries)[0];
				if ((Object)(object)val != (Object)null)
				{
					rect = val.rect;
					num = ((Rect)(ref rect)).height;
				}
			}
			float num2 = 0f;
			float num3 = 0f;
			VerticalLayoutGroup component = ((Component)contentsRect).GetComponent<VerticalLayoutGroup>();
			if ((Object)(object)component != (Object)null)
			{
				num2 = ((HorizontalOrVerticalLayoutGroup)component).spacing;
				num3 = ((LayoutGroup)component).padding.top + ((LayoutGroup)component).padding.bottom;
			}
			float num4 = 0f;
			if (num > 0f && valueOrDefault > 0)
			{
				num4 = num * (float)valueOrDefault + num2 * (float)Math.Max(0, valueOrDefault - 1) + num3;
			}
			Transform val2 = ((Component)contentsRect).transform.Find("AddNew");
			if ((Object)(object)val2 != (Object)null)
			{
				RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
				if ((Object)(object)component2 != (Object)null)
				{
					float num5 = num4;
					rect = component2.rect;
					num4 = num5 + (((Rect)(ref rect)).height + ((valueOrDefault > 0) ? num2 : 0f));
				}
			}
			if (num4 > 0f && height > 0f)
			{
				return Math.Min(height, num4);
			}
			if (num4 > 0f)
			{
				return num4;
			}
			return height;
		}

		private static void ApplyVerticalOffset(RectTransform scrollRect, int key, float verticalOffset)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)scrollRect == (Object)null))
			{
				float num = ClampOffset(verticalOffset);
				float value = 0f;
				ScrollOffsets.TryGetValue(key, out value);
				float num2 = num - value;
				scrollRect.anchoredPosition = new Vector2(scrollRect.anchoredPosition.x, scrollRect.anchoredPosition.y + num2);
				ScrollOffsets[key] = num;
			}
		}

		private static float ClampOffset(float value)
		{
			return Mathf.Clamp(value, -500f, 500f);
		}

		private static void EnsureEntryObjects(ObjectListFieldUI listUi, int maxItems)
		{
			if ((Object)(object)listUi == (Object)null)
			{
				return;
			}
			Transform contents = GetContents(listUi);
			if ((Object)(object)contents == (Object)null)
			{
				return;
			}
			Transform val = contents.Find("Entry");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			GameObject gameObject = ((Component)val).gameObject;
			for (int i = 1; i < maxItems; i++)
			{
				string text = $"Entry ({i})";
				if (!((Object)(object)contents.Find(text) != (Object)null))
				{
					((Object)Object.Instantiate<GameObject>(gameObject, contents, false)).name = text;
				}
			}
			Transform val2 = contents.Find("AddNew");
			if ((Object)(object)val2 != (Object)null)
			{
				val2.SetAsLastSibling();
			}
		}

		private static void RefreshEntryArray(ObjectListFieldUI listUi, int maxItems)
		{
			Transform contents = GetContents(listUi);
			if ((Object)(object)contents == (Object)null)
			{
				return;
			}
			RectTransform[] array = (RectTransform[])(object)new RectTransform[maxItems];
			for (int i = 0; i < maxItems; i++)
			{
				string text = ((i == 0) ? "Entry" : $"Entry ({i})");
				Transform val = contents.Find(text);
				if (!((Object)(object)val == (Object)null))
				{
					array[i] = ((Component)val).GetComponent<RectTransform>();
				}
			}
			Il2CppReferenceArray<RectTransform> val2 = new Il2CppReferenceArray<RectTransform>((long)array.Length);
			for (int j = 0; j < array.Length; j++)
			{
				((Il2CppArrayBase<RectTransform>)(object)val2)[j] = array[j];
			}
			listUi.Entries = val2;
		}

		private static void ApplyLimits(ObjectListFieldUI listUi, int maxItems, float heightOverride, float verticalOffset)
		{
			if (!((Object)(object)listUi == (Object)null))
			{
				if (maxItems < 1)
				{
					maxItems = 1;
				}
				EnsureScrollable(listUi, heightOverride, verticalOffset);
				EnsureEntryObjects(listUi, maxItems);
				RefreshEntryArray(listUi, maxItems);
				ApplyMaxItems(listUi.Fields, maxItems);
				RefreshListUi(listUi);
			}
		}

		private static void RefreshListUi(ObjectListFieldUI listUi)
		{
			if (!((Object)(object)listUi == (Object)null))
			{
				List<ObjectListField> fields = listUi.Fields;
				if (fields != null)
				{
					listUi.Bind(fields);
				}
			}
		}
	}
}
namespace MoreStations.Config
{
	public static class StationConfig
	{
		private static MelonPreferences_Category _category;

		private static bool _initialized;

		public static MelonPreferences_Entry<int> JanitorMaxStations;

		public static MelonPreferences_Entry<int> BotanistMaxStations;

		public static MelonPreferences_Entry<int> ChemistMaxStations;

		public static MelonPreferences_Entry<int> HandlerMaxStations;

		private static string ConfigPath => Path.Combine(MelonEnvironment.UserDataDirectory, "MoreStations.cfg");

		public static void Initialize()
		{
			if (_initialized)
			{
				return;
			}
			_category = MelonPreferences.CreateCategory("MoreStations", "More Stations", false, true);
			_category.SetFilePath(ConfigPath, true, false);
			JanitorMaxStations = _category.CreateEntry<int>("Janitor Station Max", 60, "Janitor Station Max", "Maximum station assignments for janitors.", false, false, (ValueValidator)null, (string)null);
			BotanistMaxStations = _category.CreateEntry<int>("Botanist Station Max", 60, "Botanist Station Max", "Maximum station assignments for botanists.", false, false, (ValueValidator)null, (string)null);
			ChemistMaxStations = _category.CreateEntry<int>("Chemist Station Max", 60, "Chemist Station Max", "Maximum station assignments for chemists.", false, false, (ValueValidator)null, (string)null);
			HandlerMaxStations = _category.CreateEntry<int>("Handler Station Max", 60, "Handler Station Max", "Maximum station assignments for handlers.", false, false, (ValueValidator)null, (string)null);
			if (!File.Exists(ConfigPath))
			{
				foreach (MelonPreferences_Entry entry in _category.Entries)
				{
					entry.ResetToDefault();
				}
				_category.SaveToFile(false);
			}
			_initialized = true;
		}
	}
}