using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.NET.Common; using BepInExResoniteShim; using Elements.Core; using FrooxEngine; using FrooxEngine.Undo; using HarmonyLib; using SkyFrost.Base; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(/*Could not decode attribute arguments.*/)] [assembly: TargetFramework(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")] [assembly: AssemblyCompany("art0007i")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.5.0")] [assembly: AssemblyInformationalVersion("1.0.5+33944bc83e7f3f769600605413ffe6e415852ad4")] [assembly: AssemblyProduct("DuplicateFix")] [assembly: AssemblyTitle("DuplicateFix")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/art0007i/DuplicateFix")] [assembly: AssemblyVersion("1.0.5.0")] [module: RefSafetyRules(11)] namespace DuplicateFix; public static class DuplicateExtensions { private static readonly global::System.Type InternalReferences = typeof(Worker).GetNestedType("InternalReferences", AccessTools.all); private static readonly MethodInfo RunDuplicate = typeof(Component).GetMethod("RunDuplicate", AccessTools.all); public static void MultiDuplicate(this global::System.Collections.Generic.IEnumerable toDuplicate, List newSlots, Slot duplicateRoot = null, bool keepGlobalTransform = true, DuplicationSettings settings = null, bool duplicateAsLocal = false) { //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) if (Enumerable.Any(toDuplicate, (Func)((Slot x) => x.IsRootSlot))) { throw new global::System.Exception("Cannot duplicate root slot"); } if (duplicateRoot != null && Enumerable.Any(toDuplicate, (Func)((Slot x) => duplicateRoot.IsChildOf(x, false)))) { throw new global::System.Exception("Target for the duplicate hierarchy cannot be within the hierarchy of the source"); } object internalReferences = InternalReferences.GetConstructor(new global::System.Type[0]).Invoke((object[])null); HashSet hashSet = Pool.BorrowHashSet(); HashSet hashSet2 = Pool.BorrowHashSet(); List postDuplication = Pool.BorrowList(); CollectionExtensions.Do(toDuplicate, (Action)delegate(Slot x) { x.ForeachComponentInChildren((Action)delegate(IDuplicationHandler h) { Action val = default(Action); h.OnBeforeDuplicate(x, ref val); if (val != null) { postDuplication.Add(val); } }, false, true); }); CollectionExtensions.Do(toDuplicate, (Action)delegate(Slot x) { x.GenerateHierarchy(hashSet2, false); }); CollectionExtensions.Do(toDuplicate, (Action)delegate(Slot x) { Traverse.Create((object)x).Method("CollectInternalReferences", new object[4] { x, internalReferences, hashSet, hashSet2 }).GetValue(); }); global::System.Collections.Generic.IEnumerator enumerator = toDuplicate.GetEnumerator(); try { while (((global::System.Collections.IEnumerator)enumerator).MoveNext()) { Slot current = enumerator.Current; newSlots.Add((Slot)((MethodBase)typeof(Slot).GetMethod("InternalDuplicate", AccessTools.all)).Invoke((object)current, new object[5] { duplicateRoot ?? current.Parent ?? ((Worker)current).World.RootSlot, internalReferences, hashSet, settings, duplicateAsLocal })); } } finally { ((global::System.IDisposable)enumerator)?.Dispose(); } if (keepGlobalTransform) { global::System.Collections.Generic.IEnumerator enumerator2 = toDuplicate.GetEnumerator(); for (int num = 0; num < newSlots.Count; num++) { if (!((global::System.Collections.IEnumerator)enumerator2).MoveNext()) { break; } newSlots[num].CopyTransform(enumerator2.Current); } } Traverse.Create(internalReferences).Method("TransferReferences", new object[1] { false }).GetValue(); List list = Pool.BorrowList(); CollectionExtensions.Do((global::System.Collections.Generic.IEnumerable)newSlots, (Action)delegate(Slot x) { x.GetComponentsInChildren(list, (Predicate)null, false, false, (Predicate)null); }); Enumerator enumerator3 = list.GetEnumerator(); try { while (enumerator3.MoveNext()) { Component current2 = enumerator3.Current; ((MethodBase)RunDuplicate).Invoke((object)current2, (object[])null); } } finally { ((global::System.IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose(); } Pool.Return(ref list); Pool.Return(ref hashSet); Traverse.Create(internalReferences).Method("Dispose", global::System.Array.Empty()); Enumerator enumerator4 = postDuplication.GetEnumerator(); try { while (enumerator4.MoveNext()) { enumerator4.Current.Invoke(); } } finally { ((global::System.IDisposable)enumerator4/*cast due to .constrained prefix*/).Dispose(); } Pool.Return(ref postDuplication); } } [ResonitePlugin("art0007i.DuplicateFix", "DuplicateFix", "1.0.5", "art0007i", "https://github.com/art0007i/DuplicateFix")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { [HarmonyPatch(typeof(Grabber), "OnFocusChanged")] private class UserspaceTransferPatch { public static bool Prefix(Grabber __instance, WorldFocus focus) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) if (!Enabled.Value) { return true; } if (!WorldPermissionsExtensoins.CanTransferObjectsOut(((Worker)__instance).World)) { return false; } Action beforeUserspaceTransfer = __instance.BeforeUserspaceTransfer; if (beforeUserspaceTransfer != null) { beforeUserspaceTransfer.Invoke(); } Traverse.Create((object)__instance).Method("CleanupGrabbed", global::System.Array.Empty()).GetValue(); if ((int)focus != 0 || !__instance.IsHoldingObjects) { return false; } global::System.Collections.Generic.IEnumerator enumerator = ((global::System.Collections.Generic.IEnumerable)__instance.GrabbedObjects).GetEnumerator(); try { while (((global::System.Collections.IEnumerator)enumerator).MoveNext()) { if (((IComponent)enumerator.Current).Slot.GetComponentInChildren((Predicate)((IItemPermissions p) => !p.CanSave), false, false) != null) { return false; } } } finally { ((global::System.IDisposable)enumerator)?.Dispose(); } float3 localPosition = __instance.HolderSlot.LocalPosition; float3 zero = float3.Zero; if ((ref localPosition) != (ref zero)) { float3 localPosition2 = __instance.HolderSlot.LocalPosition; __instance.HolderSlot.LocalPosition = float3.Zero; Enumerator enumerator2 = __instance.HolderSlot.Children.GetEnumerator(); try { while (enumerator2.MoveNext()) { Slot current = enumerator2.Current; localPosition = current.LocalPosition; current.LocalPosition = (ref localPosition) + (ref localPosition2); } } finally { ((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } if (Userspace.TryTransferToUserspaceGrabber(__instance.HolderSlot, __instance.LinkingKey)) { __instance.DestroyGrabbed(true); } return false; } } [HarmonyPatch(typeof(Userspace), "Paste")] private class UserspacePastePatch { public static bool Prefix(Userspace __instance, ref Job __result, SavedGraph data, Slot source, float3 userspacePos, floatQ userspaceRot, float3 userspaceScale, World targetWorld) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown if (!Enabled.Value) { return true; } Job task = new Job(); World world = targetWorld ?? Engine.Current.WorldManager.FocusedWorld; world.RunSynchronously((Action)delegate { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) Slot val = null; if (WorldPermissionsExtensoins.CanSpawnObjects(world)) { float3 globalPosition = WorldManager.TransferPoint(userspacePos, ((Worker)Userspace.Current).World, world); floatQ globalRotation = WorldManager.TransferRotation(userspaceRot, ((Worker)Userspace.Current).World, world); float3 globalScale = WorldManager.TransferScale(userspaceScale, ((Worker)Userspace.Current).World, world); Slot obj = source; if (((obj != null) ? ((Worker)obj).World : null) == world && !((ContainerWorker)(object)source).IsDestroyed) { source.ActiveSelf = true; source.GlobalPosition = globalPosition; source.GlobalRotation = globalRotation; source.GlobalScale = globalScale; task.SetResultAndFinish(source); } else { val = world.AddSlot("Paste", true); val.LoadObject(data.Root, (IRecord)null, (Slot)null, (Predicate)null, (ReferenceTranslator)null, (Func)null); val.GlobalPosition = globalPosition; val.GlobalRotation = globalRotation; val.GlobalScale = globalScale; Traverse.Create((object)val).Method("RunOnPaste", global::System.Array.Empty()).GetValue(); if (val.Name == "Holder") { val.Destroy(val.Parent, false); } } } if (source != null && !((ContainerWorker)(object)source).IsDestroyed) { World world2 = ((Worker)source).World; Slot obj2 = source; world2.RunSynchronously(new Action(obj2.Destroy), false, (IUpdatable)null, false); } task.SetResultAndFinish(val); }, false, (IUpdatable)null, false); __result = task; return false; } } [HarmonyPatch(typeof(InteractionHandler), "DuplicateGrabbed", new global::System.Type[] { })] private class DuplicateFixPatch { public static bool Prefix(InteractionHandler __instance) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (!Enabled.Value) { return true; } UndoManagerExtensions.BeginUndoBatch(((Worker)__instance).World, LocaleHelper.AsLocaleKey("Undo.DuplicateGrabbed", (string)null, true, (Dictionary)null)); List val = Pool.BorrowList(); List val2 = Pool.BorrowList(); try { global::System.Collections.Generic.IEnumerator enumerator = ((global::System.Collections.Generic.IEnumerable)__instance.Grabber.GrabbedObjects).GetEnumerator(); try { while (((global::System.Collections.IEnumerator)enumerator).MoveNext()) { IGrabbable current = enumerator.Current; if (__instance.Grabber.GrabbableGetComponentInParents(((IComponent)current).Slot, (Predicate)null, true) == null) { val.Add(ObjectRootExtensions.GetObjectRoot(((IComponent)current).Slot, ((Component)__instance.Grabber).Slot, false)); } } } finally { ((global::System.IDisposable)enumerator)?.Dispose(); } ((global::System.Collections.Generic.IEnumerable)val).MultiDuplicate(val2); CollectionExtensions.Do((global::System.Collections.Generic.IEnumerable)val2, (Action)delegate(Slot x) { SpawnOrDestroyExtensions.CreateSpawnUndoPoint(x, (string)null, (Action)null); }); CollectionExtensions.Do(Enumerable.SelectMany((global::System.Collections.Generic.IEnumerable)val2, (Func>)((Slot x) => (global::System.Collections.Generic.IEnumerable)x.GetComponentsInChildren((Predicate)null, false, false, (Predicate)null))), (Action)delegate(IGrabbable x) { if (x.IsGrabbed) { x.Release(x.Grabber, false); } }); } catch (global::System.Exception ex) { ((Worker)__instance).Debug.Error((object)("Exception duplicating items!\n" + (object)ex), true); } Pool.Return(ref val2); Pool.Return(ref val); UndoManagerExtensions.EndUndoBatch(((Worker)__instance).World); return false; } } internal static ManualLogSource Log; internal static ConfigEntry Enabled; public override void Load() { Log = ((BasePlugin)this).Log; Enabled = ((BasePlugin)this).Config.Bind("General", "Enabled", true, "When true the mod will be enabled."); ((BasePlugin)this).HarmonyInstance.PatchAll(); } } public static class PluginMetadata { public const string GUID = "art0007i.DuplicateFix"; public const string NAME = "DuplicateFix"; public const string VERSION = "1.0.5"; public const string AUTHORS = "art0007i"; public const string REPOSITORY_URL = "https://github.com/art0007i/DuplicateFix"; }