Decompiled source of MoreDropBoxSlots v1.0.0

MoreDropBoxSlots\MoreDropBoxSlots.dll

Decompiled 2 months ago
using System;
using System.Collections;
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 System.Text;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Networking;
using Il2CppScheduleOne.Storage;
using Il2CppSteamworks;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Preferences;
using MoreDropBoxSlots;
using MoreDropBoxSlots.Config;
using MoreDropBoxSlots.Services;
using MoreDropBoxSlots.Utility;
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(MoreDropBoxSlotsMod), "More Drop Box Slots", "1.0.0", "brobb", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: AssemblyMetadata("NexusModID", "0")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("MoreDropBoxSlots")]
[assembly: AssemblyConfiguration("IL2CPP")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MoreDropBoxSlots")]
[assembly: AssemblyTitle("MoreDropBoxSlots")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace MoreDropBoxSlots
{
	public class MoreDropBoxSlotsMod : MelonMod
	{
		public override void OnInitializeMelon()
		{
			Configuration.Instance.Load();
			Configuration.Instance.Save();
			Logger.Info("More Drop Box Slots initialized.");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			Configuration.Instance.Reset();
			if (!(sceneName != "Main"))
			{
				ConfigSyncManager.StartSync();
			}
		}
	}
}
namespace MoreDropBoxSlots.Utility
{
	public static class Logger
	{
		public static void Info(string message)
		{
			MelonLogger.Msg(message);
		}

		public static void Warning(string message)
		{
			MelonLogger.Warning(message);
		}

		public static void Error(string message)
		{
			MelonLogger.Error(message);
		}

		public static void Error(Exception exception, string message)
		{
			MelonLogger.Error($"{message} {exception}");
		}
	}
}
namespace MoreDropBoxSlots.Services
{
	public static class DropBoxSlotService
	{
		public static void ApplyToAllDeadDrops()
		{
			try
			{
				List<DeadDrop> deadDrops = DeadDrop.DeadDrops;
				if (deadDrops != null)
				{
					for (int i = 0; i < deadDrops.Count; i++)
					{
						List<DeadDrop> val = deadDrops;
						DeadDrop drop = ((Il2CppObjectBase)val[new Index(i).GetOffset(val.Count)]).Cast<DeadDrop>();
						ApplyToDeadDrop(drop);
					}
				}
			}
			catch (Exception exception)
			{
				Logger.Error(exception, "Failed to apply drop box slot changes.");
			}
		}

		public static void ApplyToDeadDrop(DeadDrop drop)
		{
			if (!((Object)(object)drop == (Object)null))
			{
				WorldStorageEntity storage = drop.Storage;
				if (!((Object)(object)storage == (Object)null))
				{
					ApplyToStorage(storage, Configuration.Instance.DropBoxSlots);
				}
			}
		}

		private static void ApplyToStorage(WorldStorageEntity storage, int targetSlots)
		{
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			int num = ClampSlots(targetSlots);
			List<ItemSlot> itemSlots = ((StorageEntity)storage).ItemSlots;
			if (itemSlots == null)
			{
				Logger.Warning("Dead drop storage ItemSlots list is null.");
				return;
			}
			int num2 = num;
			if (itemSlots.Count > num)
			{
				bool flag = true;
				for (int i = num; i < itemSlots.Count; i++)
				{
					List<ItemSlot> val = itemSlots;
					ItemSlot val2 = ((Il2CppObjectBase)val[new Index(i).GetOffset(val.Count)]).Cast<ItemSlot>();
					if (((val2 != null) ? val2.ItemInstance : null) != null)
					{
						flag = false;
						break;
					}
				}
				if (!flag)
				{
					num2 = itemSlots.Count;
					Logger.Warning($"Drop box has items beyond slot {num - 1}; keeping size at {num2}.");
				}
				else
				{
					itemSlots.RemoveRange(num, itemSlots.Count - num);
				}
			}
			if (itemSlots.Count < num)
			{
				for (int j = itemSlots.Count; j < num; j++)
				{
					ItemSlot val3 = new ItemSlot();
					if ((Delegate)(object)val3.onItemDataChanged == (Delegate)null)
					{
						val3.onItemDataChanged = Action.op_Implicit((Action)((StorageEntity)storage).ContentsChanged);
					}
					else
					{
						((Delegate)val3.onItemDataChanged).CombineImpl((Delegate)(object)Action.op_Implicit((Action)((StorageEntity)storage).ContentsChanged));
					}
					val3.SetSlotOwner(((Il2CppObjectBase)storage).Cast<IItemSlotOwner>());
				}
			}
			((StorageEntity)storage).SlotCount = num2;
			((StorageEntity)storage).DisplayRowCount = Math.Max(1, (int)Math.Ceiling((double)num2 / 5.0));
			((StorageEntity)storage).ContentsChanged();
		}

		private static int ClampSlots(int value)
		{
			int mAX_SLOTS = StorageEntity.MAX_SLOTS;
			if (value < 1)
			{
				return 1;
			}
			return (value > mAX_SLOTS) ? mAX_SLOTS : value;
		}
	}
}
namespace MoreDropBoxSlots.Patches
{
	[HarmonyPatch(typeof(DeadDrop))]
	public static class DeadDropPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Start(DeadDrop __instance)
		{
			DropBoxSlotService.ApplyToDeadDrop(__instance);
		}
	}
}
namespace MoreDropBoxSlots.Config
{
	public class Configuration
	{
		private static Configuration _instance;

		private readonly string _configFile = Path.Combine("UserData", "MoreDropBoxSlots.cfg");

		private readonly MelonPreferences_Category _dropBoxCategory;

		private readonly MelonPreferences_Entry<int> _slotCountEntry;

		public static Configuration Instance => _instance ?? (_instance = new Configuration());

		public int DropBoxSlots { get; internal set; }

		private Configuration()
		{
			_dropBoxCategory = MelonPreferences.CreateCategory("MoreDropBoxSlots");
			_dropBoxCategory.SetFilePath(_configFile, false);
			_slotCountEntry = _dropBoxCategory.CreateEntry<int>("SlotCount", 8, "Number of slots in dead drop boxes", (string)null, false, false, (ValueValidator)null, (string)null);
		}

		public void Load()
		{
			MelonPreferences.Load();
			Reset();
		}

		public void Reset()
		{
			DropBoxSlots = ClampSlots(_slotCountEntry.Value);
		}

		public void Save()
		{
			_slotCountEntry.Value = ClampSlots(DropBoxSlots);
			MelonPreferences.Save();
		}

		public void ApplyFromHost(int slots)
		{
			DropBoxSlots = ClampSlots(slots);
			_slotCountEntry.Value = DropBoxSlots;
		}

		private static int ClampSlots(int value)
		{
			int mAX_SLOTS = StorageEntity.MAX_SLOTS;
			if (value < 1)
			{
				return 1;
			}
			if (value > mAX_SLOTS)
			{
				return mAX_SLOTS;
			}
			return value;
		}
	}
	public static class ConfigSyncManager
	{
		private const string Prefix = "MoreDropBoxSlots_Config";

		private static readonly string ModVersion = typeof(MoreDropBoxSlotsMod).Assembly.GetName().Version?.ToString() ?? "1.0.0";

		public static void StartSync()
		{
			if ((Object)(object)Singleton<Lobby>.Instance == (Object)null || !Singleton<Lobby>.Instance.IsInLobby)
			{
				DropBoxSlotService.ApplyToAllDeadDrops();
			}
			else if (Singleton<Lobby>.Instance.IsHost)
			{
				SyncToClients();
				DropBoxSlotService.ApplyToAllDeadDrops();
			}
			else
			{
				MelonCoroutines.Start(WaitForPayload());
			}
		}

		private static void SyncToClients()
		{
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
			handler.AppendFormatted(ModVersion);
			handler.AppendLiteral("[");
			stringBuilder3.Append(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
			handler.AppendFormatted(Configuration.Instance.DropBoxSlots);
			handler.AppendLiteral(",");
			stringBuilder4.Append(ref handler);
			stringBuilder.Append(']');
			Logger.Info($"Syncing payload to clients: {stringBuilder}");
			Singleton<Lobby>.Instance.SetLobbyData("MoreDropBoxSlots_Config", stringBuilder.ToString());
		}

		private static IEnumerator WaitForPayload()
		{
			int i = 0;
			while (i < 10)
			{
				string payload = SteamMatchmaking.GetLobbyData(Singleton<Lobby>.Instance.LobbySteamID, "MoreDropBoxSlots_Config");
				if (string.IsNullOrEmpty(payload))
				{
					yield return (object)new WaitForSeconds(1f);
					int num = i + 1;
					i = num;
					continue;
				}
				Logger.Info("Received payload from host: " + payload);
				try
				{
					SyncFromHost(payload);
					break;
				}
				catch (Exception ex)
				{
					Exception e = ex;
					Logger.Error(e, "Error while parsing payload: " + payload);
					break;
				}
			}
		}

		private static void SyncFromHost(string payload)
		{
			string[] array = payload.Split(new char[3] { '[', ']', ',' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length < 2)
			{
				Logger.Warning("Invalid payload format: " + payload);
				return;
			}
			if (array[0] != ModVersion)
			{
				Logger.Warning("Mod version mismatch: " + array[0] + " != " + ModVersion);
				return;
			}
			if (!int.TryParse(array[1], out var result))
			{
				Logger.Warning("Invalid slot count format: " + array[1]);
				return;
			}
			Configuration.Instance.ApplyFromHost(result);
			DropBoxSlotService.ApplyToAllDeadDrops();
		}
	}
}