Decompiled source of AutomaticRematch v1.5.0

Mods/AutomaticRematch.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using AutomaticRematch;
using HarmonyLib;
using Il2CppRUMBLE.Interactions.InteractionBase;
using Il2CppRUMBLE.Managers;
using Il2CppRUMBLE.Networking.MatchFlow;
using Il2CppRUMBLE.Players.Subsystems;
using Il2CppRUMBLE.Utilities;
using MelonLoader;
using MelonLoader.Preferences;
using RumbleModdingAPI.RMAPI;
using UIFramework;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Main), "AutomaticRematch", "1.5.0", "UlvakSkillz", null)]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: MelonColor(255, 195, 0, 255)]
[assembly: MelonAuthorColor(255, 195, 0, 255)]
[assembly: VerifyLoaderVersion(0, 7, 2, true)]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("AutomaticRematch")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+375dd4674099f3e5f9cb5fca3582e93d5533c6d0")]
[assembly: AssemblyProduct("AutomaticRematch")]
[assembly: AssemblyTitle("AutomaticRematch")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace AutomaticRematch;

public enum RematchFunction
{
	None,
	Rematch,
	Requeue,
	Exit
}
public class Main : MelonMod
{
	public static class BuildInfo
	{
		public const string ModName = "AutomaticRematch";

		public const string ModVersion = "1.5.0";

		public const string Description = "Automatically Presses Rematch Button if On";

		public const string Author = "UlvakSkillz";

		public const string Company = "";
	}

	[HarmonyPatch(typeof(PlayerBoxInteractionSystem), "ExecuteFistBumpReward", new Type[] { typeof(Vector3) })]
	public static class executeFistBumpReward
	{
		private static void Postfix(ref PlayerBoxInteractionSystem __instance, ref Vector3 interactionPosition)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			__instance = ((Component)Singleton<PlayerManager>.instance.localPlayer.Controller).gameObject.GetComponent<PlayerBoxInteractionSystem>();
			if (Preferences.PrefRematchType.Value != RematchTypes.RematchOnFistbump)
			{
				return;
			}
			float num = Vector3.Distance(interactionPosition, (Preferences.PrefPrimaryHand.Value == Hand.Right) ? ((Component)__instance.rightHandTrigger).transform.position : ((Component)__instance.leftHandTrigger).transform.position);
			float num2 = Vector3.Distance(interactionPosition, (Preferences.PrefPrimaryHand.Value != Hand.Right) ? ((Component)__instance.rightHandTrigger).transform.position : ((Component)__instance.leftHandTrigger).transform.position);
			if (!inMatch)
			{
				if (Math.Abs(num - num2) < 0.01f)
				{
					Log("Distance Between Hands too close to same distance, skipping");
				}
				else if (num < num2)
				{
					Log("Rematch on Fistbump Rematching");
					((InteractionButton)GetRematchButton().GetComponent<RematchButton>()).RPC_OnToggleStateChanged(true);
				}
				else
				{
					if (Preferences.PrefSecondaryHandFunction.Value == Function.None)
					{
						return;
					}
					watchingPlayerCount = false;
					if (Preferences.PrefSecondaryHandFunction.Value == Function.Requeue)
					{
						Log("Rematch on Fistbump secondaryHandFunction Requeueing");
						UnityEvent onPressed = ((InteractionButton)((Component)GetRequeueButton().transform.GetChild(1).GetChild(0)).GetComponent<RematchButton>()).OnPressed;
						try
						{
							onPressed.Invoke();
						}
						catch (Exception ex)
						{
							Log("MatchEnded Requeue Error OnPressed.Invoke");
							Error(ex.InnerException);
						}
						GetRequeueButton().GetComponent<MatchHandlerInvoker>().Requeue(Singleton<PlayerManager>.instance.localPlayer);
					}
					else if (Preferences.PrefSecondaryHandFunction.Value == Function.Exit)
					{
						Log("Rematch on Fistbump secondaryHandFunction Quiting");
						UnityEvent onPressed2 = ((Component)GetExitButton().transform.GetChild(1).GetChild(0)).GetComponent<InteractionButton>().OnPressed;
						try
						{
							onPressed2.Invoke();
						}
						catch (Exception ex2)
						{
							Log("MatchEnded Exit Error OnPressed.Invoke");
							Error(ex2.InnerException);
						}
						GetExitButton().GetComponent<MatchHandlerInvoker>().Quit(Singleton<PlayerManager>.instance.localPlayer);
					}
				}
				return;
			}
			Log("Fistbump Happened, Waiting for Sign");
			needsToRunFunction = true;
			if (num < num2)
			{
				rematchFunctionToRun = RematchFunction.None;
			}
			else if (Preferences.PrefSecondaryHandFunction.Value != 0)
			{
				if (Preferences.PrefSecondaryHandFunction.Value == Function.Requeue)
				{
					rematchFunctionToRun = RematchFunction.Requeue;
				}
				else
				{
					rematchFunctionToRun = RematchFunction.Exit;
				}
			}
		}
	}

	[CompilerGenerated]
	private sealed class <MatchEndedAutoPress>d__15 : IEnumerator<object>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private object <>2__current;

		public Main <>4__this;

		private float <buttonValue>5__1;

		private ControllerButtons <>s__2;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <MatchEndedAutoPress>d__15(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(Preferences.PrefTimeBeforeRematch.Value);
				<>1__state = 1;
				return true;
			case 1:
			{
				<>1__state = -1;
				<buttonValue>5__1 = 0f;
				ControllerButtons value = Preferences.PrefPreventAutoRematchButton.Value;
				<>s__2 = value;
				switch (<>s__2)
				{
				case ControllerButtons.LeftControllerTrigger:
					<buttonValue>5__1 = LeftController.GetTrigger();
					break;
				case ControllerButtons.LeftControllerPrimary:
					<buttonValue>5__1 = LeftController.GetPrimary();
					break;
				case ControllerButtons.LeftControllerSecondary:
					<buttonValue>5__1 = LeftController.GetSecondary();
					break;
				case ControllerButtons.RightControllerTrigger:
					<buttonValue>5__1 = RightController.GetTrigger();
					break;
				case ControllerButtons.RightControllerPrimary:
					<buttonValue>5__1 = RightController.GetPrimary();
					break;
				case ControllerButtons.RightControllerSecondary:
					<buttonValue>5__1 = RightController.GetSecondary();
					break;
				}
				if (!Preferences.PrefPreventAutoRematchButtonEnabled.Value || <buttonValue>5__1 < 0.5f)
				{
					((InteractionButton)GetRematchButton().GetComponent<RematchButton>()).RPC_OnToggleStateChanged(true);
				}
				return false;
			}
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <WatchPlayerCount>d__13 : IEnumerator<object>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private object <>2__current;

		public Main <>4__this;

		private OnePlayerFunction <>s__1;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <WatchPlayerCount>d__13(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				Log("WatchPlayerCount Start");
				watchingPlayerCount = true;
				Log("Adding Watchers");
				((Component)GetExitButton().transform.FindChild("InteractionButton/Button")).GetComponent<InteractionButton>().OnPressed.AddListener(UnityAction.op_Implicit((Action)delegate
				{
					<>4__this.LeavingMatch();
				}));
				Log("Watcher Exit Button Added");
				((Component)GetRequeueButton().transform.FindChild("InteractionButton/Button")).GetComponent<InteractionButton>().OnPressed.AddListener(UnityAction.op_Implicit((Action)delegate
				{
					<>4__this.LeavingMatch();
				}));
				Log("Watcher Requeue Button Added");
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if (watchingPlayerCount && Singleton<PlayerManager>.instance.AllPlayers.Count > 1)
			{
				<>2__current = (object)new WaitForFixedUpdate();
				<>1__state = 1;
				return true;
			}
			Log($"WatchPlayerCount -WHILE LOOP- Done. watchingPlayerCount: {watchingPlayerCount} | PlayerCount: {Singleton<PlayerManager>.instance.AllPlayers.Count}");
			if (watchingPlayerCount)
			{
				OnePlayerFunction value = Preferences.PrefOnePlayerRemain.Value;
				<>s__1 = value;
				switch (<>s__1)
				{
				case OnePlayerFunction.SecondaryHandFunction:
					if (Preferences.PrefOnePlayerRemain.Value == OnePlayerFunction.SecondaryHandFunction)
					{
						Log("onePlayerRemainFunction - Secondary Hand Function Requeueing");
						GetRequeueButton().GetComponent<MatchHandlerInvoker>().Requeue(Singleton<PlayerManager>.instance.localPlayer);
					}
					else if (Preferences.PrefOnePlayerRemain.Value == OnePlayerFunction.Exit)
					{
						Log("onePlayerRemainFunction - Secondary Hand Function Exiting");
						GetExitButton().GetComponent<MatchHandlerInvoker>().Quit(Singleton<PlayerManager>.instance.localPlayer);
					}
					break;
				case OnePlayerFunction.Requeue:
					Log("onePlayerRemainFunction - Requeueing");
					GetRequeueButton().GetComponent<MatchHandlerInvoker>().Requeue(Singleton<PlayerManager>.instance.localPlayer);
					break;
				case OnePlayerFunction.Exit:
					Log("onePlayerRemainFunction - Exiting");
					GetExitButton().GetComponent<MatchHandlerInvoker>().Quit(Singleton<PlayerManager>.instance.localPlayer);
					break;
				}
			}
			return false;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	private static string currentScene = "Loader";

	private static bool needsToRunFunction = false;

	private static bool inMatch = false;

	private static bool watchingPlayerCount = false;

	private static RematchFunction rematchFunctionToRun;

	private static void Log(string msg)
	{
		if (Preferences.PrefDebugging.Value)
		{
			Melon<Main>.Logger.Msg(msg);
		}
	}

	private static void Error(Exception msg)
	{
		if (Preferences.PrefDebugging.Value)
		{
			Melon<Main>.Logger.Error((object)msg);
		}
	}

	public override void OnInitializeMelon()
	{
		Preferences.InitPrefs();
		UI.Register((MelonMod)(object)this, (MelonPreferences_Category[])(object)new MelonPreferences_Category[3]
		{
			Preferences.AutomaticRematchCategory,
			Preferences.AutoPressSettingsCategory,
			Preferences.FistbumpSettingsCategory
		});
	}

	public override void OnLateInitializeMelon()
	{
		Actions.onMatchEnded += MatchEnded;
		Actions.onMatchStarted += matchStarted;
	}

	private void matchStarted()
	{
		inMatch = true;
	}

	public override void OnSceneWasLoaded(int buildIndex, string sceneName)
	{
		currentScene = sceneName;
		inMatch = false;
		watchingPlayerCount = false;
	}

	private void MatchEnded()
	{
		Log("MatchEnded()");
		inMatch = false;
		if (Preferences.PrefRematchType.Value == RematchTypes.AutoRematch)
		{
			Log("PrefRematchType is RematchTypes.AutoRematch");
			MelonCoroutines.Start(MatchEndedAutoPress());
		}
		if (Preferences.PrefRematchType.Value == RematchTypes.RematchOnFistbump && needsToRunFunction)
		{
			Log("Running Function from Fistbump Prior");
			switch (rematchFunctionToRun)
			{
			case RematchFunction.Rematch:
				Log("Running Function Rematch");
				((InteractionButton)GetRematchButton().GetComponent<RematchButton>()).RPC_OnToggleStateChanged(true);
				break;
			case RematchFunction.Requeue:
			{
				Log("Running Function Requeue");
				UnityEvent onPressed2 = ((InteractionButton)((Component)GetRequeueButton().transform.GetChild(1).GetChild(0)).GetComponent<RematchButton>()).OnPressed;
				try
				{
					onPressed2.Invoke();
				}
				catch (Exception ex2)
				{
					Log("MatchEnded Requeue Error OnPressed.Invoke");
					Error(ex2.InnerException);
				}
				GetRequeueButton().GetComponent<MatchHandlerInvoker>().Requeue(Singleton<PlayerManager>.instance.localPlayer);
				break;
			}
			case RematchFunction.Exit:
			{
				Log("Running Function Exit");
				UnityEvent onPressed = ((Component)GetExitButton().transform.GetChild(1).GetChild(0)).GetComponent<InteractionButton>().OnPressed;
				try
				{
					onPressed.Invoke();
				}
				catch (Exception ex)
				{
					Log("MatchEnded Exit Error OnPressed.Invoke");
					Error(ex.InnerException);
				}
				GetExitButton().GetComponent<MatchHandlerInvoker>().Quit(Singleton<PlayerManager>.instance.localPlayer);
				needsToRunFunction = false;
				rematchFunctionToRun = RematchFunction.None;
				return;
			}
			}
			needsToRunFunction = false;
			rematchFunctionToRun = RematchFunction.None;
		}
		MelonCoroutines.Start(WatchPlayerCount());
	}

	[IteratorStateMachine(typeof(<WatchPlayerCount>d__13))]
	private IEnumerator WatchPlayerCount()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <WatchPlayerCount>d__13(0)
		{
			<>4__this = this
		};
	}

	private void LeavingMatch()
	{
		Log("LeavingMatch()");
		watchingPlayerCount = false;
	}

	[IteratorStateMachine(typeof(<MatchEndedAutoPress>d__15))]
	private IEnumerator MatchEndedAutoPress()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <MatchEndedAutoPress>d__15(0)
		{
			<>4__this = this
		};
	}

	private static GameObject GetRematchButton()
	{
		return Players.IsHost() ? GetHostRematchButton() : GetClientRematchButton();
	}

	private static GameObject GetRequeueButton()
	{
		return Players.IsHost() ? GetHostRequeueButton() : GetClientRequeueButton();
	}

	private static GameObject GetExitButton()
	{
		return Players.IsHost() ? GetHostExitButton() : GetClientExitButton();
	}

	private static GameObject GetHostRematchButton()
	{
		return (currentScene == "Map0") ? Button.GetGameObject() : Button.GetGameObject();
	}

	private static GameObject GetHostRequeueButton()
	{
		return (currentScene == "Map0") ? Requeuebutton.GetGameObject() : Requeuebutton.GetGameObject();
	}

	private static GameObject GetHostExitButton()
	{
		return (currentScene == "Map0") ? Exitmatchbutton.GetGameObject() : Exitmatchbutton.GetGameObject();
	}

	private static GameObject GetClientRematchButton()
	{
		return (currentScene == "Map0") ? Button.GetGameObject() : Button.GetGameObject();
	}

	private static GameObject GetClientRequeueButton()
	{
		return (currentScene == "Map0") ? Requeuebutton.GetGameObject() : Requeuebutton.GetGameObject();
	}

	private static GameObject GetClientExitButton()
	{
		return (currentScene == "Map0") ? Exitmatchbutton.GetGameObject() : Exitmatchbutton.GetGameObject();
	}
}
public enum RematchTypes
{
	[Display(Name = "Game Default")]
	None,
	[Display(Name = "Timed")]
	AutoRematch,
	[Display(Name = "On Fistbump")]
	RematchOnFistbump
}
public enum ControllerButtons
{
	[Display(Name = "None")]
	None,
	[Display(Name = "Left Controller Trigger")]
	LeftControllerTrigger,
	[Display(Name = "Left Controller Primary")]
	LeftControllerPrimary,
	[Display(Name = "Left Controller Secondary")]
	LeftControllerSecondary,
	[Display(Name = "Right Controller Trigger")]
	RightControllerTrigger,
	[Display(Name = "Right Controller Primary")]
	RightControllerPrimary,
	[Display(Name = "Right Controller Secondary")]
	RightControllerSecondary
}
public enum Hand
{
	[Display(Name = "Left Hand")]
	Left,
	[Display(Name = "Right Hand")]
	Right
}
public enum Function
{
	[Display(Name = "Do Nothing")]
	None,
	[Display(Name = "Press Requeue")]
	Requeue,
	[Display(Name = "Press Exit")]
	Exit
}
public enum OnePlayerFunction
{
	[Display(Name = "Do Nothing")]
	None,
	[Display(Name = "Secondary Hand Function")]
	SecondaryHandFunction,
	[Display(Name = "Press Requeue")]
	Requeue,
	[Display(Name = "Press Exit")]
	Exit
}
public class Preferences
{
	private const string CONFIG_FILE = "config.cfg";

	private const string USER_DATA = "UserData/AutomaticRematch/";

	internal static Dictionary<MelonPreferences_Entry, object> LastSavedValues = new Dictionary<MelonPreferences_Entry, object>();

	internal static MelonPreferences_Category AutomaticRematchCategory;

	internal static MelonPreferences_Entry<RematchTypes> PrefRematchType;

	internal static MelonPreferences_Entry<OnePlayerFunction> PrefOnePlayerRemain;

	internal static MelonPreferences_Entry<bool> PrefDebugging;

	internal static MelonPreferences_Category AutoPressSettingsCategory;

	internal static MelonPreferences_Entry<float> PrefTimeBeforeRematch;

	internal static MelonPreferences_Entry<bool> PrefPreventAutoRematchButtonEnabled;

	internal static MelonPreferences_Entry<ControllerButtons> PrefPreventAutoRematchButton;

	internal static MelonPreferences_Category FistbumpSettingsCategory;

	internal static MelonPreferences_Entry<Hand> PrefPrimaryHand;

	internal static MelonPreferences_Entry<Function> PrefSecondaryHandFunction;

	internal static void InitPrefs()
	{
		if (!Directory.Exists("UserData/AutomaticRematch/"))
		{
			Directory.CreateDirectory("UserData/AutomaticRematch/");
		}
		AutomaticRematchCategory = MelonPreferences.CreateCategory("AutomaticRematch", "Rematch Type");
		AutomaticRematchCategory.SetFilePath(Path.Combine("UserData/AutomaticRematch/", "config.cfg"));
		PrefRematchType = AutomaticRematchCategory.CreateEntry<RematchTypes>("RematchType", RematchTypes.AutoRematch, "Rematch Confirmation Type", "Selects what type of Rematch Confirmation to use", false, false, (ValueValidator)null, (string)null);
		PrefOnePlayerRemain = AutomaticRematchCategory.CreateEntry<OnePlayerFunction>("OnePlayerRemain", OnePlayerFunction.None, "Other Player Leaves Function", "Sets the Function for When One Player Remains", false, false, (ValueValidator)null, (string)null);
		PrefDebugging = AutomaticRematchCategory.CreateEntry<bool>("Debug", false, "Debugging", "Toggles Debugging On/Off", false, false, (ValueValidator)null, (string)null);
		AutoPressSettingsCategory = MelonPreferences.CreateCategory("TimedSettings", "Timed Settings");
		AutoPressSettingsCategory.SetFilePath(Path.Combine("UserData/AutomaticRematch/", "config.cfg"));
		PrefTimeBeforeRematch = AutoPressSettingsCategory.CreateEntry<float>("TimeBeforeRematch", 0f, "Time Before Rematch", "Time to Wait before it Presses Rematch", false, false, (ValueValidator)(object)new ValueRange<float>(0f, float.MaxValue), (string)null);
		PrefPreventAutoRematchButtonEnabled = AutoPressSettingsCategory.CreateEntry<bool>("PreventAutoRematchButtonEnabled", true, "Prevent Auto Rematch Button Enabled", "Toggles Button to Stop Rematching On/Off", false, false, (ValueValidator)null, (string)null);
		PrefPreventAutoRematchButton = AutoPressSettingsCategory.CreateEntry<ControllerButtons>("PreventAutoRematchButton", ControllerButtons.LeftControllerTrigger, "Prevent Auto Rematch Button", "Sets What Button it Watches to Prevent Automatic Rematching", false, false, (ValueValidator)null, (string)null);
		FistbumpSettingsCategory = MelonPreferences.CreateCategory("FistbumpSettings", "Fistbump Settings");
		FistbumpSettingsCategory.SetFilePath(Path.Combine("UserData/AutomaticRematch/", "config.cfg"));
		PrefPrimaryHand = FistbumpSettingsCategory.CreateEntry<Hand>("PrimaryHand", Hand.Right, "Primary Hand", "Sets the Primary Hand for Fistbump Actions", false, false, (ValueValidator)null, (string)null);
		PrefSecondaryHandFunction = FistbumpSettingsCategory.CreateEntry<Function>("SecondaryHandFunction", Function.None, "Secondary Hand Function", "Sets the Secondary Hand Function for Fistbump Actions", false, false, (ValueValidator)null, (string)null);
		StoreLastSavedPrefs();
	}

	internal static void StoreLastSavedPrefs()
	{
		List<MelonPreferences_Entry> list = new List<MelonPreferences_Entry>();
		list.AddRange(AutomaticRematchCategory.Entries);
		list.AddRange(AutoPressSettingsCategory.Entries);
		list.AddRange(FistbumpSettingsCategory.Entries);
		foreach (MelonPreferences_Entry item in list)
		{
			LastSavedValues[item] = item.BoxedValue;
		}
	}
}