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<Grabber>((Predicate<Grabber>)((Grabber gr) => BodyNodeExtensions.GetChirality(((SyncField<BodyNode>)(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<IValueSource>(Enumerable.Select<IGrabbable, IValueSource>((global::System.Collections.Generic.IEnumerable<IGrabbable>)grabber.GrabbedObjects, (Func<IGrabbable, IValueSource>)((IGrabbable gr) => ((ContainerWorker<Component>)(object)((IComponent)gr).Slot).GetComponent<IValueSource>((Predicate<IValueSource>)null, false))), (Func<IValueSource, bool>)((IValueSource p) => p != null));
}
public static ValueProxy<T>? GetValueProxy<T>(this Grabber grabber)
{
return Enumerable.FirstOrDefault<ValueProxy<T>>(Enumerable.Select<IGrabbable, ValueProxy<T>>((global::System.Collections.Generic.IEnumerable<IGrabbable>)grabber.GrabbedObjects, (Func<IGrabbable, ValueProxy<T>>)((IGrabbable gr) => ((ContainerWorker<Component>)(object)((IComponent)gr).Slot).GetComponent<ValueProxy<T>>((Predicate<ValueProxy<T>>)null, false))), (Func<ValueProxy<T>, bool>)((ValueProxy<T> p) => p != null));
}
public static ReferenceProxy? GetReferenceProxy(this Grabber grabber)
{
return Enumerable.FirstOrDefault<ReferenceProxy>(Enumerable.Select<IGrabbable, ReferenceProxy>((global::System.Collections.Generic.IEnumerable<IGrabbable>)grabber.GrabbedObjects, (Func<IGrabbable, ReferenceProxy>)((IGrabbable gr) => ((ContainerWorker<Component>)(object)((IComponent)gr).Slot).GetComponent<ReferenceProxy>((Predicate<ReferenceProxy>)null, false))), (Func<ReferenceProxy, bool>)((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<T>(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<ColorDriver>((global::System.Collections.Generic.IEnumerable<ColorDriver>)((InteractionElement)obj).ColorDrivers, (Action<ColorDriver>)delegate(ColorDriver cd)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
((SyncField<colorX>)(object)cd.PressColor).Value = ((SyncField<colorX>)(object)cd.HighlightColor).Value;
});
ValueCopyExtensions.DriveFrom((IField)(object)((ContainerWorker<Component>)(object)((Component)obj).Slot).AttachComponent<ValueProxySource<T>>(true, (Action<ValueProxySource<T>>)null).Value, field, false, false, true);
((ContainerWorker<Component>)(object)((Component)obj).Slot).AttachComponent<ValueReceiver<T>>(true, (Action<ValueReceiver<T>>)null).Field.Target = (IField<T>)(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<IGrabbable> grabbedObjects = val.GrabbedObjects;
float3 globalPosition = ((Component)val).Slot.GlobalPosition;
return !__instance.TryReceive((global::System.Collections.Generic.IEnumerable<IGrabbable>)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<Grabber>((Predicate<Grabber>)((Grabber gr) => (int)((SyncField<BodyNode>)(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<BodyNode>)(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.Type>((global::System.Collections.Generic.IEnumerable<global::System.Type>)((object)obj).GetType().GenericTypeArguments) : null);
}
else
{
type = ((object)((SyncRef<IWorldElement>)(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<string>);
type = typeof(string);
}
__instance.SpawnNode(type2, (Action<ProtoFluxNode>)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<IWorldElement>)(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<float2>)(object)((IComponent)__result).Slot.GetComponentInChildren<Canvas>((Predicate<Canvas>)null, false, false).Size).Value = new float2(0f, 32f);
Sync<string> content = ((IComponent)__result).Slot.GetComponentInChildren<Text>((Predicate<Text>)null, false, false).Content;
((SyncField<string>)(object)content).Value = ((SyncField<string>)(object)content).Value + "\n" + ReflectionExtensions.GetNiceName(((object)target).GetType(), "<", ">", "+");
}
if (ReferenceProxyTypeName.Value)
{
((SyncField<string>)(object)((ContainerWorker<Component>)(object)((IComponent)__result).Slot).AttachComponent<ValueProxy<string>>(true, (Action<ValueProxy<string>>)null).Value).Value = ((object)target).GetType().FullName;
}
}
}
public static readonly Uri grabIcon = new Uri("resdb:///702b51521a39f6a0e5d5d36b2675638e90d395695134678e04151c9a78cbfd6f");
internal static ManualLogSource Log;
internal static ConfigEntry<bool> ReferenceProxyVisual;
internal static ConfigEntry<bool> ReferenceProxyTypeName;
internal static ConfigEntry<bool> ProxyTransfer;
internal static ConfigEntry<bool> CreateInputs;
internal static ConfigEntry<bool> ClickValues;
internal static ConfigEntry<bool> InspectorButtons;
public override void Load()
{
Log = ((BasePlugin)this).Log;
ReferenceProxyVisual = ((BasePlugin)this).Config.Bind<bool>("General", "ReferenceProxyVisual", true, "Determines whether text containing reference type should be generated on reference proxies.");
ReferenceProxyTypeName = ((BasePlugin)this).Config.Bind<bool>("General", "ReferenceProxyTypeName", false, "Determines whether reference proxies should act as value proxies with the full type name.");
ProxyTransfer = ((BasePlugin)this).Config.Bind<bool>("General", "ProxyTransfer", true, "Determines whether value proxies should be allowed to be clicked in to userspace and back.");
CreateInputs = ((BasePlugin)this).Config.Bind<bool>("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<bool>("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<bool>("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";
}