Decompiled source of MassParenting v1.0.0

plugins/MassParenting.dll

Decompiled 4 days ago
using 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 BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using VGEditor;
using VGFunctions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MassParenting")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Example Custom Trigger")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b1ecd2008cd6968df0efc94fc73af5d4b75f0e35")]
[assembly: AssemblyProduct("MassParenting")]
[assembly: AssemblyTitle("MassParenting")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 MassParenting
{
	[HarmonyPatch(typeof(EditorManager))]
	internal static class EditorManagerPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void PostSetup(ref EditorManager __instance)
		{
			Transform val = ((Component)__instance).transform.parent.Find("Editor GUI/sizer/EditorDialogs/GameObjectDialog/data/left/Scroll View/Viewport/Content/parent");
			Transform val2 = ((Component)__instance).transform.parent.Find("Editor GUI/sizer/EditorDialogs/MultiObjectDialog/data/Viewport/Content");
			Transform val3 = Object.Instantiate<Transform>(val, val2);
			val3.SetSiblingIndex(16);
			((Object)val3).name = "mass parent";
			((Component)val3.Find("parent_more")).gameObject.SetActive(false);
			((Component)val3.Find("row-1")).gameObject.SetActive(false);
			((Component)val3.Find("row-2/children")).gameObject.SetActive(false);
			((Component)val3.Find("row-2/expand")).gameObject.SetActive(false);
			Transform child = val3.parent.GetChild(8);
			((Component)child).gameObject.SetActive(true);
			child.SetSiblingIndex(15);
			Object.Instantiate<Transform>(val3.parent.GetChild(10), val3.parent).SetSiblingIndex(17);
		}
	}
	[HarmonyPatch(typeof(EditorElement_MultiObjectPanel))]
	public static class MultiObjectPanelPatch
	{
		public static bool IsSelectionObject;

		[HarmonyPatch("OnRender")]
		[HarmonyPostfix]
		private static void PostRender(EditorElement_MultiObjectPanel __instance)
		{
			IsSelectionObject = false;
			UpdateParentUI(__instance);
		}

		[HarmonyPatch("OnUnRender")]
		[HarmonyPostfix]
		private static void PostUnRender(EditorElement_MultiObjectPanel __instance)
		{
			IsSelectionObject = false;
		}

		private static void UpdateParentUI(EditorElement_MultiObjectPanel __instance)
		{
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Expected O, but got Unknown
			Transform val = ((Component)__instance).transform.Find("data/Viewport/Content/mass parent");
			Dictionary<ObjectSelection, string> undoDict = new Dictionary<ObjectSelection, string>(SingletonBase<ObjectEditor>.Inst.SelectedObjects.Count);
			foreach (ObjectSelection selectedObject in SingletonBase<ObjectEditor>.Inst.SelectedObjects)
			{
				undoDict[selectedObject] = selectedObject.GetObjectData().parent;
			}
			CompLib.InitButton(((Component)val).transform.Find("row-2/parent-camera"), (Action)delegate
			{
				SetParentOfAllSelection("camera");
			}, (Action)delegate
			{
				SetParentOfAllSelection("");
				foreach (KeyValuePair<ObjectSelection, string> item in undoDict)
				{
					SetParent(item.Key, item.Value);
				}
			}, "set parent to camera");
			CompLib.InitToggle(((Component)val).transform.Find("row-2/parent-picker"), (Func<bool>)(() => IsSelectionObject), (Action<bool>)delegate(bool _new)
			{
				EditorManager.inst.DisplayNotification("Select an object from the timeline or viewport to parent to.", 3f, (NotificationType)3);
				IsSelectionObject = _new;
			}, (Func<bool>)(() => true), "select parent from timeline");
			CompLib.InitButton(((Component)val).transform.Find("row-2/parent"), (Action)delegate
			{
				EditorElement<EditorElement_ParentSelector>.inst.OpenType((SelectorType)1);
			}, (Action)delegate
			{
				((EditorElement<EditorElement_ParentSelector>)(object)EditorElement<EditorElement_ParentSelector>.inst).Close();
			}, "open parent selector");
			string mainParent = SingletonBase<ObjectEditor>.Inst.MainSelectedObject.GetObjectData().parent;
			if (!string.IsNullOrEmpty(mainParent) && (SingletonBase<ObjectEditor>.Inst.MainSelectedObject.isParentedToCamera() || DataManager.inst.gameData.beatmapObjects.Find((BeatmapObject x) => x.id == mainParent) != null))
			{
				BeatmapObject val2 = DataManager.inst.gameData.beatmapObjects.Find((BeatmapObject x) => x.id == mainParent);
				new ObjectSelection((SelectionType)0, mainParent);
				((Component)((Component)val).transform.Find("row-1")).gameObject.SetActive(true);
				((Component)((Component)val).transform.Find("row-2/pos")).gameObject.SetActive(!SingletonBase<ObjectEditor>.Inst.MainSelectedObject.isParentedToCamera());
				((Component)((Component)val).transform.Find("row-2/sca")).gameObject.SetActive(!SingletonBase<ObjectEditor>.Inst.MainSelectedObject.isParentedToCamera());
				((Component)((Component)val).transform.Find("row-2/rot")).gameObject.SetActive(!SingletonBase<ObjectEditor>.Inst.MainSelectedObject.isParentedToCamera());
				Dictionary<ObjectSelection, string> undoDict2 = new Dictionary<ObjectSelection, string>(SingletonBase<ObjectEditor>.Inst.SelectedObjects.Count);
				foreach (ObjectSelection selectedObject2 in SingletonBase<ObjectEditor>.Inst.SelectedObjects)
				{
					undoDict2[selectedObject2] = selectedObject2.GetObjectData().parent;
				}
				CompLib.InitButton(((Component)val).transform.Find("row-1/clear-parent"), (Action)delegate
				{
					SetParentOfAllSelection("");
				}, (Action)delegate
				{
					SetParentOfAllSelection("");
					foreach (KeyValuePair<ObjectSelection, string> item2 in undoDict2)
					{
						SetParent(item2.Key, item2.Value);
					}
				}, "clear object parent");
				ObjectSelection val3 = new ObjectSelection((SelectionType)0, SingletonBase<ObjectEditor>.Inst.MainSelectedObject.ID);
				((Selectable)((Component)((Component)val).transform.Find("row-1/text")).GetComponent<Button>()).interactable = !val3.isParentedToCamera();
				SelectionSet<ObjectSelection> oldSelection = new SelectionSet<ObjectSelection>();
				foreach (ObjectSelection selectedObject3 in SingletonBase<ObjectEditor>.Inst.SelectedObjects)
				{
					oldSelection.Add(selectedObject3, true);
				}
				CompLib.InitButton(((Component)val).transform.Find("row-1/text"), (Action)delegate
				{
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					//IL_001c: Expected O, but got Unknown
					ObjectSelection val4 = new ObjectSelection((SelectionType)0, SingletonBase<ObjectEditor>.Inst.MainSelectedObject.GetObjectData().parent);
					SingletonBase<ObjectEditor>.Inst.OpenObject(val4);
				}, (Action)delegate
				{
					SingletonBase<ObjectEditor>.Inst.ClearSelection(true);
					foreach (ObjectSelection item3 in oldSelection)
					{
						SingletonBase<ObjectEditor>.Inst.AddToSelection(item3, true);
					}
					SingletonBase<ObjectEditor>.Inst.OpenObjectDialog();
				}, "select parent");
				((TMP_Text)((Component)((Component)val).transform.Find("row-1/text/text")).GetComponent<TextMeshProUGUI>()).text = (val3.isParentedToCamera() ? "<i>Game Camera</i>" : val2.name);
				CompLib.InitToggle(((Component)val).transform.Find("row-2/pos"), (Func<bool>)(() => SingletonBase<ObjectEditor>.Inst.MainSelectedObject.GetObjectData().GetParentType(0)), (Action<bool>)delegate(bool _new)
				{
					foreach (ObjectSelection selectedObject4 in SingletonBase<ObjectEditor>.Inst.SelectedObjects)
					{
						selectedObject4.GetObjectData().SetParentType(0, _new);
						ObjectManager.inst.UpdateObject(selectedObject4, false);
					}
				}, (Func<bool>)(() => ((EditorElement<EditorElement_MultiObjectPanel>)(object)__instance).isActive), "position parent offset");
				CompLib.InitToggle(((Component)val).transform.Find("row-2/sca"), (Func<bool>)(() => SingletonBase<ObjectEditor>.Inst.MainSelectedObject.GetObjectData().GetParentType(1)), (Action<bool>)delegate(bool _new)
				{
					foreach (ObjectSelection selectedObject5 in SingletonBase<ObjectEditor>.Inst.SelectedObjects)
					{
						selectedObject5.GetObjectData().SetParentType(1, _new);
						ObjectManager.inst.UpdateObject(selectedObject5, false);
					}
				}, (Func<bool>)(() => ((EditorElement<EditorElement_MultiObjectPanel>)(object)__instance).isActive), "scale parent offset");
				CompLib.InitToggle(((Component)val).transform.Find("row-2/rot"), (Func<bool>)(() => SingletonBase<ObjectEditor>.Inst.MainSelectedObject.GetObjectData().GetParentType(2)), (Action<bool>)delegate(bool _new)
				{
					foreach (ObjectSelection selectedObject6 in SingletonBase<ObjectEditor>.Inst.SelectedObjects)
					{
						selectedObject6.GetObjectData().SetParentType(2, _new);
						ObjectManager.inst.UpdateObject(selectedObject6, false);
					}
				}, (Func<bool>)(() => ((EditorElement<EditorElement_MultiObjectPanel>)(object)__instance).isActive), "rotation parent offset");
			}
			else
			{
				((Component)((Component)val).transform.Find("row-1")).gameObject.SetActive(false);
				((Component)((Component)val).transform.Find("parent_more")).gameObject.SetActive(false);
				((Component)((Component)val).transform.Find("row-2/pos")).gameObject.SetActive(false);
				((Component)((Component)val).transform.Find("row-2/sca")).gameObject.SetActive(false);
				((Component)((Component)val).transform.Find("row-2/rot")).gameObject.SetActive(false);
			}
		}

		public static void SetParentOfAllSelection(string _parent)
		{
			foreach (ObjectSelection selectedObject in SingletonBase<ObjectEditor>.Inst.SelectedObjects)
			{
				SetParent(selectedObject, _parent);
			}
		}

		public static void SetParent(ObjectSelection selection, string _parent)
		{
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Invalid comparison between Unknown and I4
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			BeatmapObject val = DataManager.inst.gameData.beatmapObjects[selection.Index];
			string id = val.id;
			if (id == _parent)
			{
				EditorManager.inst.DisplayNotification("You can't parent an object to itself... what you thinkin'!?", 2f, (NotificationType)1);
				return;
			}
			Dictionary<string, BeatmapObject> dictionary = DataManager.inst.gameData.beatmapObjects.ToDictionary((BeatmapObject x) => x.id, (BeatmapObject x) => x);
			if (SingletonBase<ObjectEditor>.Inst.CheckForParentLoopsOptimized(_parent, id, dictionary))
			{
				EditorManager.inst.DisplayNotification("Oops that would make a parent chain sorry no can do!", 2f, (NotificationType)1);
				return;
			}
			if (SingletonBase<ObjectEditor>.Inst.CalculateParentChainLength(_parent, dictionary) >= 16)
			{
				EditorManager.inst.DisplayNotification("You can't have more than 15 parents in a parent chain", 2f, (NotificationType)1);
				return;
			}
			IsSelectionObject = false;
			val.parent = _parent;
			val.ParentType = "111";
			if (_parent == "camera")
			{
				Queue<string> queue = new Queue<string>();
				queue.Enqueue(id);
				while (queue.Count > 0)
				{
					string text = queue.Dequeue();
					if (!dictionary.TryGetValue(text, out var value))
					{
						continue;
					}
					if ((int)value.renderLayer != 1)
					{
						value.renderLayer = (RenderLayer)1;
						if (text != id)
						{
							ObjectManager.inst.UpdateObject(new ObjectSelection((SelectionType)0, text), false);
						}
					}
					foreach (BeatmapObject beatmapObject in DataManager.inst.gameData.beatmapObjects)
					{
						if (beatmapObject.parent == text)
						{
							queue.Enqueue(beatmapObject.id);
						}
					}
				}
			}
			ObjectManager.inst.UpdateObject(selection, false);
		}
	}
	internal static class ObjectEditorPatch
	{
		internal static bool PreCreateTriggerInfoDelegate(BaseEventData eventData, ObjectSelection ____obj)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			PointerEventData val = (PointerEventData)eventData;
			if ((int)val.button == 0 && !SingletonBase<ObjectEditor>.Inst.beatmapObjectsDrag)
			{
				if (MultiObjectPanelPatch.IsSelectionObject && ____obj.IsObject())
				{
					Dictionary<ObjectSelection, string> undoDict = new Dictionary<ObjectSelection, string>(SingletonBase<ObjectEditor>.Inst.SelectedObjects.Count);
					foreach (ObjectSelection selectedObject in SingletonBase<ObjectEditor>.Inst.SelectedObjects)
					{
						undoDict[selectedObject] = selectedObject.GetObjectData().parent;
					}
					EditorManager.inst.history.Add(new Command("set parent", (Action)delegate
					{
						string text = ____obj.GetObjectData()?.name ?? "Unknown Object";
						EditorManager.inst.DisplayNotification("Parent set to: " + text, 2f, (NotificationType)0);
						MultiObjectPanelPatch.SetParentOfAllSelection(____obj.ID);
					}, (Action)delegate
					{
						MultiObjectPanelPatch.SetParentOfAllSelection("");
						foreach (KeyValuePair<ObjectSelection, string> item in undoDict)
						{
							MultiObjectPanelPatch.SetParent(item.Key, item.Value);
						}
					}, false), true);
					return false;
				}
				if (MultiObjectPanelPatch.IsSelectionObject && ____obj.IsPrefab())
				{
					EditorManager.inst.DisplayNotification("Cannot set a prefab or its children as a parent. Please select a valid object.", 2f, (NotificationType)1);
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ParentScrollController))]
	internal static class ParentScrollPatch
	{
		private static bool _patched = false;

		private static Dictionary<ObjectSelection, string> _undoDict = new Dictionary<ObjectSelection, string>();

		[HarmonyPatch("AddToData")]
		[HarmonyPostfix]
		private static void PostAdd(Data _data)
		{
			if (!_patched)
			{
				_patched = true;
				Plugin.Inst.PatchParentSelector(_data);
			}
			_undoDict.Clear();
			foreach (ObjectSelection selectedObject in SingletonBase<ObjectEditor>.Inst.SelectedObjects)
			{
				_undoDict[selectedObject] = selectedObject.GetObjectData().parent;
			}
		}

		internal static void PostClickAction(object __instance, BeatmapObject ___obj)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			object? value = __instance.GetType().GetFields()[1].GetValue(__instance);
			EditorElement_ParentSelector val = (EditorElement_ParentSelector)((value is EditorElement_ParentSelector) ? value : null);
			if ((int)val.selectorType == 1)
			{
				MultiObjectPanelPatch.SetParentOfAllSelection(___obj.id);
			}
		}

		internal static void PostUndoAction(object __instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			object? value = __instance.GetType().GetFields()[1].GetValue(__instance);
			EditorElement_ParentSelector val = (EditorElement_ParentSelector)((value is EditorElement_ParentSelector) ? value : null);
			if ((int)val.selectorType != 1)
			{
				return;
			}
			MultiObjectPanelPatch.SetParentOfAllSelection("");
			foreach (KeyValuePair<ObjectSelection, string> item in _undoDict)
			{
				MultiObjectPanelPatch.SetParent(item.Key, item.Value);
			}
		}
	}
	[BepInPlugin("me.ytarame.MassParenting", "MassParenting", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static Plugin Inst;

		private Harmony _harmony;

		private const string Guid = "me.ytarame.MassParenting";

		private const string Name = "MassParenting";

		private const string Version = "1.0.0";

		public static ManualLogSource Log => ((BaseUnityPlugin)Inst).Logger;

		private void Awake()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			Inst = this;
			_harmony = new Harmony("me.ytarame.MassParenting");
			_harmony.PatchAll();
			MethodInfo createTriggerIndo = GetCreateTriggerIndo();
			if (createTriggerIndo == null)
			{
				((BaseUnityPlugin)this).Logger.LogFatal((object)"Could not find create trigger info, the mod will not work, report this.");
			}
			else
			{
				_harmony.Patch((MethodBase)createTriggerIndo, new HarmonyMethod(typeof(ObjectEditorPatch).GetMethod("PreCreateTriggerInfoDelegate", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin me.ytarame.MassParenting is loaded!");
		}

		public void PatchParentSelector(Data data)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			_harmony.Patch((MethodBase)data.clickAction.Method, (HarmonyMethod)null, new HarmonyMethod(typeof(ParentScrollPatch).GetMethod("PostClickAction", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_harmony.Patch((MethodBase)data.clickActionUndo.Method, (HarmonyMethod)null, new HarmonyMethod(typeof(ParentScrollPatch).GetMethod("PostUndoAction", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private MethodInfo GetCreateTriggerIndo()
		{
			Type[] nestedTypes = typeof(ObjectEditor).GetNestedTypes(BindingFlags.NonPublic);
			Type[] array = nestedTypes;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.Name.Contains("<CreateBeatmapObjectTrigger>b__0"))
					{
						return methodInfo;
					}
				}
			}
			return null;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "MassParenting";

		public const string PLUGIN_NAME = "MassParenting";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}