using System; 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.ProtoFlux; using FrooxEngine.ProtoFlux.Runtimes.Execution.Nodes; using FrooxEngine.UIX; using HarmonyLib; using Renderite.Shared; [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("2.1.5.0")] [assembly: AssemblyInformationalVersion("2.1.5+da544c0bcb1037de007784cef6ea435b7b1ff7c9")] [assembly: AssemblyProduct("ValueProxyExtensions")] [assembly: AssemblyTitle("ValueProxyExtensions")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/art0007i/ValueProxyExtensions")] [assembly: AssemblyVersion("2.1.5.0")] [module: RefSafetyRules(11)] namespace ValueProxyExtensions; internal static class GrabberExtensions { public static Grabber FindSidedGrabberWithProxy(this Slot slot, Chirality side) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return slot.GetComponentInChildren((Predicate)((Grabber gr) => BodyNodeExtensions.GetChirality(((SyncField)(object)gr.CorrespondingBodyNode).Value) == side && gr.HasProxy()), false, false); } public static bool HasProxy(this Grabber grabber) { if (grabber.GetValueProxy() == null) { return grabber.GetReferenceProxy() != null; } return true; } public static IValueSource? GetValueProxy(this Grabber grabber) { return Enumerable.FirstOrDefault(Enumerable.Select((global::System.Collections.Generic.IEnumerable)grabber.GrabbedObjects, (Func)((IGrabbable gr) => ((ContainerWorker)(object)((IComponent)gr).Slot).GetComponent((Predicate)null, false))), (Func)((IValueSource p) => p != null)); } public static ValueProxy? GetValueProxy(this Grabber grabber) { return Enumerable.FirstOrDefault>(Enumerable.Select>((global::System.Collections.Generic.IEnumerable)grabber.GrabbedObjects, (Func>)((IGrabbable gr) => ((ContainerWorker)(object)((IComponent)gr).Slot).GetComponent>((Predicate>)null, false))), (Func, bool>)((ValueProxy p) => p != null)); } public static ReferenceProxy? GetReferenceProxy(this Grabber grabber) { return Enumerable.FirstOrDefault(Enumerable.Select((global::System.Collections.Generic.IEnumerable)grabber.GrabbedObjects, (Func)((IGrabbable gr) => ((ContainerWorker)(object)((IComponent)gr).Slot).GetComponent((Predicate)null, false))), (Func)((ReferenceProxy p) => p != null)); } } [ResonitePlugin("art0007i.ValueProxyExtensions", "ValueProxyExtensions", "2.1.5", "art0007i", "https://github.com/art0007i/ValueProxyExtensions")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { [HarmonyPatch(typeof(SyncMemberEditorBuilder))] private class InspectorFieldPatch { public static MethodInfo GrabButtonMethod = AccessTools.Method(typeof(InspectorFieldPatch), "BuildGrabButton", (global::System.Type[])null, (global::System.Type[])null); [HarmonyPostfix] [HarmonyPatch("BuildMemberEditors")] public static void InspectorFieldBuilder(IField field, global::System.Type type, UIBuilder ui, string path) { if (InspectorButtons.Value && !type.IsPrimitive && !(type == typeof(string)) && !(type == typeof(Uri)) && !(type == typeof(global::System.Type)) && !(type == typeof(decimal)) && type.GetFields((BindingFlags)52).Length != 0) { ((MethodBase)GrabButtonMethod.MakeGenericMethod(new global::System.Type[1] { type })).Invoke((object)null, new object[4] { field, type, ui, path }); } } public static void BuildGrabButton(IField field, global::System.Type type, UIBuilder ui, string path = null) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(path)) { ui.PushStyle(); ui.Style.MinWidth = 24f; ui.Style.ButtonColor = new colorX(0.7f, 0.7f, 1f, 1f, (ColorProfile)1); Button obj = ui.Button(grabIcon); CollectionExtensions.Do((global::System.Collections.Generic.IEnumerable)((InteractionElement)obj).ColorDrivers, (Action)delegate(ColorDriver cd) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) ((SyncField)(object)cd.PressColor).Value = ((SyncField)(object)cd.HighlightColor).Value; }); ValueCopyExtensions.DriveFrom((IField)(object)((ContainerWorker)(object)((Component)obj).Slot).AttachComponent>(true, (Action>)null).Value, field, false, false, true); ((ContainerWorker)(object)((Component)obj).Slot).AttachComponent>(true, (Action>)null).Field.Target = (IField)(object)field; ui.PopStyle(); } } } [HarmonyPatch(typeof(TextField), "FrooxEngine.IButtonPressReceiver.Pressed")] private class TextFieldPatch { public static bool Prefix(ButtonEventData eventData, TextField __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!ClickValues.Value) { return true; } Grabber val = UserHelper.TryFindGrabberWithItems(eventData.source.Slot); if (val != null && val.GetValueProxy() != null) { global::System.Collections.Generic.IReadOnlyList grabbedObjects = val.GrabbedObjects; float3 globalPosition = ((Component)val).Slot.GlobalPosition; return !__instance.TryReceive((global::System.Collections.Generic.IEnumerable)grabbedObjects, (Component)(object)val, (InteractionData)null, ref globalPosition); } return true; } } [HarmonyPatch(typeof(UserHelper), "TryFindGrabberWithItems")] private class GrabberChiralityFix { public static bool Prefix(Slot source, ref Grabber __result) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) UserRoot activeUserRoot = source.ActiveUserRoot; if (activeUserRoot == null) { return true; } Grabber val = ((Component)activeUserRoot).Slot.GetComponentInChildren((Predicate)((Grabber gr) => (int)((SyncField)(object)gr.CorrespondingBodyNode).Value != 0 && source.IsChildOf(((Component)gr).Slot.Parent.Parent, false)), false, false); if (val == null) { return true; } Chirality chirality = BodyNodeExtensions.GetChirality(((SyncField)(object)val.CorrespondingBodyNode).Value); Chirality other = BodyNodeExtensions.GetOther(chirality); if ((int)chirality < 0) { return true; } if (!val.HasProxy()) { val = null; } User localUser = (WorldExtensions.IsUserspace(((Worker)source).World) ? ((Worker)source).Engine.WorldManager.FocusedWorld : Userspace.UserspaceWorld).LocalUser; Slot val2 = ((localUser != null) ? ((Component)localUser.Root).Slot : null); if (val == null && val2 != null && ProxyTransfer.Value) { val = val2.FindSidedGrabberWithProxy(chirality); } if (val == null) { val = ((Component)activeUserRoot).Slot.FindSidedGrabberWithProxy(other); } if (val == null && val2 != null && ProxyTransfer.Value) { val = val2.FindSidedGrabberWithProxy(other); } if (val != null) { __result = val; return false; } return true; } } [HarmonyPatch(typeof(ProtoFluxTool), "OnSecondaryPress")] private class FluxToolPatch { public static bool Prefix(ProtoFluxTool __instance) { if (!CreateInputs.Value) { return true; } InteractionHandler activeHandler = ((Tool)__instance).ActiveHandler; Grabber val = ((activeHandler != null) ? activeHandler.Grabber : null); if (val == null) { return true; } IValueSource valProx = null; ReferenceProxy refProx = val.GetReferenceProxy(); global::System.Type type = null; if (refProx == null) { valProx = val.GetValueProxy(); IValueSource obj = valProx; type = ((obj != null) ? Enumerable.FirstOrDefault((global::System.Collections.Generic.IEnumerable)((object)obj).GetType().GenericTypeArguments) : null); } else { type = ((object)((SyncRef)(object)refProx.Reference).Target)?.GetType(); } if (type != (global::System.Type)null) { global::System.Type type2 = ProtoFluxHelper.GetInputNode(type); if (type2 == (global::System.Type)null) { type2 = typeof(ValueObjectInput); type = typeof(string); } __instance.SpawnNode(type2, (Action)delegate(ProtoFluxNode node) { if (refProx != null) { Traverse obj2 = Traverse.Create((object)node).Field("Target"); if (obj2 != null) { Traverse obj3 = obj2.Property("Target", (object[])null); if (obj3 != null) { obj3.SetValue((object)((SyncRef)(object)refProx.Reference).Target); } } } if (valProx != null) { Traverse obj4 = Traverse.Create((object)node).Field("Value"); if (obj4 != null) { Traverse obj5 = obj4.Property("Value", (object[])null); if (obj5 != null) { obj5.SetValue(valProx.BoxedValue); } } } }); return false; } return true; } } [HarmonyPatch(typeof(ReferenceProxy), "Construct")] private class ReferenceProxyExtensiomsPatch { public static void Postfix(IGrabbable __result, IWorldElement target) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (ReferenceProxyVisual.Value) { ((SyncField)(object)((IComponent)__result).Slot.GetComponentInChildren((Predicate)null, false, false).Size).Value = new float2(0f, 32f); Sync content = ((IComponent)__result).Slot.GetComponentInChildren((Predicate)null, false, false).Content; ((SyncField)(object)content).Value = ((SyncField)(object)content).Value + "\n" + ReflectionExtensions.GetNiceName(((object)target).GetType(), "<", ">", "+"); } if (ReferenceProxyTypeName.Value) { ((SyncField)(object)((ContainerWorker)(object)((IComponent)__result).Slot).AttachComponent>(true, (Action>)null).Value).Value = ((object)target).GetType().FullName; } } } public static readonly Uri grabIcon = new Uri("resdb:///702b51521a39f6a0e5d5d36b2675638e90d395695134678e04151c9a78cbfd6f"); internal static ManualLogSource Log; internal static ConfigEntry ReferenceProxyVisual; internal static ConfigEntry ReferenceProxyTypeName; internal static ConfigEntry ProxyTransfer; internal static ConfigEntry CreateInputs; internal static ConfigEntry ClickValues; internal static ConfigEntry InspectorButtons; public override void Load() { Log = ((BasePlugin)this).Log; ReferenceProxyVisual = ((BasePlugin)this).Config.Bind("General", "ReferenceProxyVisual", true, "Determines whether text containing reference type should be generated on reference proxies."); ReferenceProxyTypeName = ((BasePlugin)this).Config.Bind("General", "ReferenceProxyTypeName", false, "Determines whether reference proxies should act as value proxies with the full type name."); ProxyTransfer = ((BasePlugin)this).Config.Bind("General", "ProxyTransfer", true, "Determines whether value proxies should be allowed to be clicked in to userspace and back."); CreateInputs = ((BasePlugin)this).Config.Bind("General", "CreateInputs", true, "Determines whether pressing secondary with a value or reference proxy in hand will create a ProtoFlux input with that value."); ClickValues = ((BasePlugin)this).Config.Bind("General", "ClickValues", true, "Determines whether pressing primary while hovering over a text field while holding a value proxy will put the held value into that field."); InspectorButtons = ((BasePlugin)this).Config.Bind("General", "InspectorButtons", false, "Determines whether inspector panels should generate the pick value button."); ((BasePlugin)this).HarmonyInstance.PatchAll(); } } public static class PluginMetadata { public const string GUID = "art0007i.ValueProxyExtensions"; public const string NAME = "ValueProxyExtensions"; public const string VERSION = "2.1.5"; public const string AUTHORS = "art0007i"; public const string REPOSITORY_URL = "https://github.com/art0007i/ValueProxyExtensions"; }