Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of AutoWater v0.3.0
Mods/AutoWater.dll
Decompiled a day agousing System; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AutoWater; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(AutoWaterMod), "AutoWater", "0.3.0", "Michiyo", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("AutoWater")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+1b7452ddf18bc9456145b87296c3d822aeac4a9e")] [assembly: AssemblyProduct("AutoWater")] [assembly: AssemblyTitle("AutoWater")] [assembly: NeutralResourcesLanguage("en-US")] [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 AutoWater { public class AutoWaterMod : MelonMod { private MelonPreferences_Category _category; private MelonPreferences_Entry<double> _waterThreshold; private MelonPreferences_Entry<double> _checkInterval; private float _lastCheckTime = 0f; public override void OnInitializeMelon() { _category = MelonPreferences.CreateCategory("AutoWater", "AutoWater Settings"); _waterThreshold = _category.CreateEntry<double>("WaterThreshold", 0.3, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); ((MelonPreferences_Entry)_waterThreshold).Comment = "Water pots when they fall below this percentage. Default is 0.3 (30%)"; _checkInterval = _category.CreateEntry<double>("CheckInterval", 60.0, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); ((MelonPreferences_Entry)_checkInterval).Comment = "Time (in seconds) between sprinkler checks"; MelonLogger.Msg($"[AutoWater] Config loaded: Threshold={_waterThreshold.Value}, Interval={_checkInterval.Value}"); } public override void OnUpdate() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (!(name != "Main")) { float realtimeSinceStartup = Time.realtimeSinceStartup; float num = realtimeSinceStartup - _lastCheckTime; if ((double)num >= _checkInterval.Value) { _lastCheckTime = realtimeSinceStartup; MelonCoroutines.Start(ProcessAllSprinklers()); } } } private IEnumerator ProcessAllSprinklers() { MonoBehaviour[] sprinklers = Object.FindObjectsOfType<MonoBehaviour>(); MonoBehaviour[] array = sprinklers; foreach (MonoBehaviour obj in array) { if (((object)obj).GetType().FullName != "ScheduleOne.ObjectScripts.Sprinkler") { continue; } Type type = ((object)obj).GetType(); MethodInfo getPotsMethod = type.GetMethod("GetPots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo waterMethod = type.GetMethod("Water", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (getPotsMethod == null || waterMethod == null) { continue; } object potList = getPotsMethod.Invoke(obj, null); if (potList == null) { continue; } foreach (object pot in (IEnumerable)potList) { if (pot == null) { continue; } Type potType = pot.GetType(); PropertyInfo isFilledField = potType.GetProperty("IsFilledWithSoil", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); PropertyInfo normWaterLevelProp = potType.GetProperty("NormalizedWaterLevel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); PropertyInfo plantProp = potType.GetProperty("Plant", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(isFilledField == null) && !(normWaterLevelProp == null) && !(plantProp == null)) { bool isFilled = (bool)isFilledField.GetValue(pot); float waterLevel = (float)normWaterLevelProp.GetValue(pot); bool hasPlant = plantProp.GetValue(pot) != null; if (isFilled && hasPlant && (double)waterLevel < _waterThreshold.Value) { waterMethod.Invoke(obj, null); break; } } } } yield return null; } } }