using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.NET.Common;
using BepInExResoniteShim;
using FrooxEngine;
using HarmonyLib;
[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: IgnoresAccessChecksTo("FrooxEngine")]
[assembly: AssemblyCompany("art0007i")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+4dab396263fbcb85c3d90d2ac087321aa0cbf953")]
[assembly: AssemblyProduct("BetterGrabRotate")]
[assembly: AssemblyTitle("BetterGrabRotate")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/art0007i/BetterGrabRotate")]
[assembly: SecurityPermission((SecurityAction)8, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace BetterGrabRotate
{
[ResonitePlugin("art0007i.BetterGrabRotate", "BetterGrabRotate", "1.0.1", "art0007i", "https://github.com/art0007i/BetterGrabRotate")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BasePlugin
{
[HarmonyPatch(typeof(InteractionHandler), "OnLaserHoldInputUpdate")]
public static class BetterGrabPatch
{
public class GrabState
{
public double lastClickTime = -1.0;
public double doubleClickLockout = -1.0;
}
[CompilerGenerated]
private sealed class <Transpiler>d__2 : System.Collections.Generic.IEnumerable<CodeInstruction>, System.Collections.IEnumerable, System.Collections.Generic.IEnumerator<CodeInstruction>, System.Collections.IEnumerator, System.IDisposable
{
private int <>1__state;
private CodeInstruction <>2__current;
private int <>l__initialThreadId;
private System.Collections.Generic.IEnumerable<CodeInstruction> codes;
public System.Collections.Generic.IEnumerable<CodeInstruction> <>3__codes;
private bool <found>5__2;
private bool <replaceNext>5__3;
private FieldInfo <lookFor>5__4;
private System.Collections.Generic.IEnumerator<CodeInstruction> <>7__wrap4;
private CodeInstruction <code>5__6;
CodeInstruction System.Collections.Generic.IEnumerator<CodeInstruction>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object System.Collections.IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <Transpiler>d__2(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void System.IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || (uint)(num - 1) <= 2u)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<lookFor>5__4 = null;
<>7__wrap4 = null;
<code>5__6 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Expected O, but got Unknown
//IL_0099: 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_00a9: Expected O, but got Unknown
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<found>5__2 = false;
<replaceNext>5__3 = false;
<lookFor>5__4 = AccessTools.Field(typeof(LaserHoldInputs), "Align");
<>7__wrap4 = codes.GetEnumerator();
<>1__state = -3;
break;
case 1:
<>1__state = -3;
<>2__current = new CodeInstruction(OpCodes.Call, (object)((System.Delegate)(object)new Func<DigitalAction, InteractionHandler, bool>(Inject)).Method);
<>1__state = 2;
return true;
case 2:
<>1__state = -3;
goto IL_0126;
case 3:
{
<>1__state = -3;
goto IL_0126;
}
IL_0126:
if (CodeInstructionExtensions.LoadsField(<code>5__6, <lookFor>5__4, false))
{
<replaceNext>5__3 = true;
}
<code>5__6 = null;
break;
}
if (((System.Collections.IEnumerator)<>7__wrap4).MoveNext())
{
<code>5__6 = <>7__wrap4.Current;
if (<replaceNext>5__3)
{
<found>5__2 = true;
<replaceNext>5__3 = false;
<>2__current = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
<>1__state = 1;
return true;
}
<>2__current = <code>5__6;
<>1__state = 3;
return true;
}
<>m__Finally1();
<>7__wrap4 = null;
if (!<found>5__2)
{
Log.LogError((object)"Failed to patch, the mod will not work.");
}
return false;
}
catch
{
//try-fault
((System.IDisposable)this).Dispose();
throw;
}
}
bool System.Collections.IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
if (<>7__wrap4 != null)
{
((System.IDisposable)<>7__wrap4).Dispose();
}
}
[DebuggerHidden]
void System.Collections.IEnumerator.Reset()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
throw new NotSupportedException();
}
[DebuggerHidden]
System.Collections.Generic.IEnumerator<CodeInstruction> System.Collections.Generic.IEnumerable<CodeInstruction>.GetEnumerator()
{
<Transpiler>d__2 <Transpiler>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<Transpiler>d__ = this;
}
else
{
<Transpiler>d__ = new <Transpiler>d__2(0);
}
<Transpiler>d__.codes = <>3__codes;
return <Transpiler>d__;
}
[DebuggerHidden]
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return (System.Collections.IEnumerator)((System.Collections.Generic.IEnumerable<CodeInstruction>)this).GetEnumerator();
}
}
public static ConditionalWeakTable<InteractionHandler, GrabState> grabStates = new ConditionalWeakTable<InteractionHandler, GrabState>();
[IteratorStateMachine(typeof(<Transpiler>d__2))]
public static System.Collections.Generic.IEnumerable<CodeInstruction> Transpiler(System.Collections.Generic.IEnumerable<CodeInstruction> codes)
{
bool found = false;
bool replaceNext = false;
FieldInfo lookFor = AccessTools.Field(typeof(LaserHoldInputs), "Align");
System.Collections.Generic.IEnumerator<CodeInstruction> enumerator = codes.GetEnumerator();
try
{
while (((System.Collections.IEnumerator)enumerator).MoveNext())
{
CodeInstruction code = enumerator.Current;
if (replaceNext)
{
found = true;
replaceNext = false;
yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null);
yield return new CodeInstruction(OpCodes.Call, (object)((System.Delegate)(object)new Func<DigitalAction, InteractionHandler, bool>(Inject)).Method);
}
else
{
yield return code;
}
if (CodeInstructionExtensions.LoadsField(code, lookFor, false))
{
replaceNext = true;
}
}
}
finally
{
((System.IDisposable)enumerator)?.Dispose();
}
if (!found)
{
Log.LogError((object)"Failed to patch, the mod will not work.");
}
}
public static bool Inject(DigitalAction orig, InteractionHandler handler)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Invalid comparison between Unknown and I4
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Expected O, but got Unknown
if (!Enable.Value || (DisableOnDesktop.Value && !((Worker)handler).InputInterface.VR_Active))
{
return orig.Pressed;
}
GrabState orCreateValue = grabStates.GetOrCreateValue(handler);
bool flag = (int)((SyncField<LaserRotationType>)(object)handler._laserRotationType).Value == 3;
bool value = ClickToggle.Value;
if (orig.Pressed)
{
if (((Worker)handler).Time.WorldTime - orCreateValue.lastClickTime < 0.5)
{
((ComponentBase<Component>)(object)handler).RunSynchronously(new Action(handler.AlignHeldItem), false);
orCreateValue.lastClickTime = -1.0;
orCreateValue.doubleClickLockout = ((Worker)handler).Time.WorldTime + LockoutTime.Value;
if (value)
{
handler.SwitchLaserRotation((LaserRotationType)1);
}
}
else
{
orCreateValue.lastClickTime = ((Worker)handler).Time.WorldTime;
if (value)
{
handler.SwitchLaserRotation((LaserRotationType)(flag ? 1 : 3));
}
}
}
if (value)
{
return false;
}
bool flag2 = ((Worker)handler).Time.WorldTime >= orCreateValue.doubleClickLockout;
if ((orig.Held && flag2) != flag)
{
handler.SwitchLaserRotation((LaserRotationType)(flag ? 1 : 3));
}
return false;
}
}
internal static ManualLogSource Log;
internal static ConfigEntry<bool> Enable;
internal static ConfigEntry<bool> DisableOnDesktop;
internal static ConfigEntry<bool> ClickToggle;
internal static ConfigEntry<double> LockoutTime;
public override void Load()
{
Log = ((BasePlugin)this).Log;
Enable = ((BasePlugin)this).Config.Bind<bool>("General", "Enable", true, "When true the mod will be enabled.");
DisableOnDesktop = ((BasePlugin)this).Config.Bind<bool>("General", "DisableOnDesktop", false, "When true, the mod will be disabled in desktop mode, since free rotate in desktop behaves kinda weird anyway.");
ClickToggle = ((BasePlugin)this).Config.Bind<bool>("General", "ClickToggle", false, "When true each click will toggle free rotate, when false free rotate is activated by just holding trigger. (but a double click will still align flat in both cases)");
LockoutTime = ((BasePlugin)this).Config.Bind<double>("General", "LockoutTime", 0.5, "When click toggle is OFF, this setting will determine the minimum amount of time to enable free rotate after performing an align.\n\nIf this was didn't exist, you'd basically be guaranteed to nudge the object's rotation after aligning it.");
((BasePlugin)this).HarmonyInstance.PatchAll();
}
public override bool Unload()
{
((BasePlugin)this).HarmonyInstance.UnpatchSelf();
return true;
}
}
public static class PluginMetadata
{
public const string GUID = "art0007i.BetterGrabRotate";
public const string NAME = "BetterGrabRotate";
public const string VERSION = "1.0.1";
public const string AUTHORS = "art0007i";
public const string REPOSITORY_URL = "https://github.com/art0007i/BetterGrabRotate";
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(/*Could not decode attribute arguments.*/)]
internal sealed class IgnoresAccessChecksToAttribute : System.Attribute
{
internal IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}