using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using Il2CppSLZ.Marrow;
using K0COM.MasterCoreHandAssist;
using MelonLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "MasterCore Hand Assist", "1.0.0", "K0COM", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("0.0.0.0")]
[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 K0COM.MasterCoreHandAssist
{
public sealed class Mod : MelonMod
{
private sealed class PendingCartridge
{
public readonly GameObject Root;
public readonly int InstanceId;
public readonly float DiscoveredAt;
public float NextAttemptAt;
public int Attempts;
public PendingCartridge(GameObject root, int instanceId, float discoveredAt, float nextAttemptAt)
{
Root = root;
InstanceId = instanceId;
DiscoveredAt = discoveredAt;
NextAttemptAt = nextAttemptAt;
Attempts = 0;
}
}
private const string CartridgeMarkerName = "K0COM_MASTERCORE_CARTRIDGE_MARKER";
private const string ProcessedMarkerPrefix = "K0COM_MASTERCORE_CARTRIDGE_PROCESSED_";
private const string DeviceMarkerName = "K0COM_MASTERCORE_DEVICE_MARKER";
private const float DiscoveryInterval = 0.035f;
private const float InitialAttachDelay = 0.1f;
private const float RetryInterval = 0.1f;
private const float GiveUpAfterSeconds = 3f;
private const int MaxDiscoveriesPerTick = 16;
private readonly List<PendingCartridge> _pending = new List<PendingCartridge>();
private float _nextDiscoveryTime;
public override void OnInitializeMelon()
{
((MelonBase)this).LoggerInstance.Msg("MasterCore Hand Assist 1.0.0 loaded.");
((MelonBase)this).LoggerInstance.Msg("Waiting for K0COM Master Core cartridge markers.");
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
_pending.Clear();
_nextDiscoveryTime = 0f;
}
public override void OnUpdate()
{
float unscaledTime = Time.unscaledTime;
if (unscaledTime >= _nextDiscoveryTime)
{
_nextDiscoveryTime = unscaledTime + 0.035f;
DiscoverNewCartridges(unscaledTime);
}
ProcessPendingCartridges(unscaledTime);
}
private void DiscoverNewCartridges(float now)
{
for (int i = 0; i < 16; i++)
{
GameObject val = GameObject.Find("K0COM_MASTERCORE_CARTRIDGE_MARKER");
if ((Object)(object)val == (Object)null)
{
break;
}
((Object)val).name = "K0COM_MASTERCORE_CARTRIDGE_PROCESSED_" + ((Object)val).GetInstanceID();
Transform parent = val.transform.parent;
if ((Object)(object)parent == (Object)null)
{
((MelonBase)this).LoggerInstance.Warning("Found a Master Core marker without a parent object.");
continue;
}
GameObject gameObject = ((Component)parent).gameObject;
int instanceID = ((Object)gameObject).GetInstanceID();
if (!ContainsPendingId(instanceID))
{
_pending.Add(new PendingCartridge(gameObject, instanceID, now, now + 0.1f));
}
}
}
private bool ContainsPendingId(int instanceId)
{
for (int i = 0; i < _pending.Count; i++)
{
if (_pending[i].InstanceId == instanceId)
{
return true;
}
}
return false;
}
private void ProcessPendingCartridges(float now)
{
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
for (int num = _pending.Count - 1; num >= 0; num--)
{
PendingCartridge pendingCartridge = _pending[num];
if ((Object)(object)pendingCartridge.Root == (Object)null)
{
_pending.RemoveAt(num);
}
else if (!(now < pendingCartridge.NextAttemptAt))
{
if (now - pendingCartridge.DiscoveredAt > 3f)
{
((MelonBase)this).LoggerInstance.Warning("Could not find a free hand for a Master Core cartridge. It was left at the physical fallback spawn point.");
_pending.RemoveAt(num);
}
else
{
Hand val = SelectTargetHand(pendingCartridge.Root);
if ((Object)(object)val == (Object)null)
{
pendingCartridge.NextAttemptAt = now + 0.1f;
pendingCartridge.Attempts++;
}
else if (TryAttachToHand(pendingCartridge.Root, val))
{
((MelonBase)this).LoggerInstance.Msg("Placed Master Core cartridge into " + ((object)val.handedness/*cast due to .constrained prefix*/).ToString() + " hand.");
_pending.RemoveAt(num);
}
else
{
pendingCartridge.NextAttemptAt = now + 0.1f;
pendingCartridge.Attempts++;
}
}
}
}
}
private Hand SelectTargetHand(GameObject cartridge)
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
if (!Player.HandsExist)
{
return null;
}
Hand leftHand = Player.LeftHand;
Hand rightHand = Player.RightHand;
if ((Object)(object)leftHand == (Object)null || (Object)(object)rightHand == (Object)null)
{
return null;
}
GameObject objectInHand = Player.GetObjectInHand(leftHand);
GameObject objectInHand2 = Player.GetObjectInHand(rightHand);
bool flag = IsMasterCoreDevice(objectInHand);
bool flag2 = IsMasterCoreDevice(objectInHand2);
bool flag3 = (Object)(object)objectInHand == (Object)null;
bool flag4 = (Object)(object)objectInHand2 == (Object)null;
if (flag && flag4)
{
return rightHand;
}
if (flag2 && flag3)
{
return leftHand;
}
if (flag || flag2)
{
return null;
}
if (flag3 && flag4)
{
float num = PalmDistanceSquared(leftHand, cartridge.transform.position);
float num2 = PalmDistanceSquared(rightHand, cartridge.transform.position);
if (!(num <= num2))
{
return rightHand;
}
return leftHand;
}
if (flag3)
{
return leftHand;
}
if (flag4)
{
return rightHand;
}
return null;
}
private static float PalmDistanceSquared(Hand hand, Vector3 position)
{
//IL_0023: 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_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)hand == (Object)null || (Object)(object)hand.palmPositionTransform == (Object)null)
{
return float.MaxValue;
}
Vector3 val = hand.palmPositionTransform.position - position;
return ((Vector3)(ref val)).sqrMagnitude;
}
private static bool IsMasterCoreDevice(GameObject heldObject)
{
if ((Object)(object)heldObject == (Object)null)
{
return false;
}
Transform root = heldObject.transform.root;
if ((Object)(object)root == (Object)null)
{
return false;
}
if ((Object)(object)root.Find("K0COM_MASTERCORE_DEVICE_MARKER") != (Object)null)
{
return true;
}
if (((Object)root).name.IndexOf("MasterCore", StringComparison.OrdinalIgnoreCase) < 0)
{
return ((Object)root).name.IndexOf("Master Core", StringComparison.OrdinalIgnoreCase) >= 0;
}
return true;
}
private bool TryAttachToHand(GameObject cartridgeRoot, Hand targetHand)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)cartridgeRoot == (Object)null || (Object)(object)targetHand == (Object)null)
{
return false;
}
if ((Object)(object)Player.GetObjectInHand(targetHand) != (Object)null)
{
return false;
}
Transform palmPositionTransform = targetHand.palmPositionTransform;
if ((Object)(object)palmPositionTransform != (Object)null)
{
cartridgeRoot.transform.position = palmPositionTransform.position;
cartridgeRoot.transform.rotation = palmPositionTransform.rotation;
}
Rigidbody component = cartridgeRoot.GetComponent<Rigidbody>();
if ((Object)(object)component != (Object)null)
{
component.velocity = Vector3.zero;
component.angularVelocity = Vector3.zero;
component.useGravity = true;
component.WakeUp();
}
Grip componentInChildren = cartridgeRoot.GetComponentInChildren<Grip>(true);
GameObject val = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).gameObject : cartridgeRoot);
targetHand.AttachObject(val);
return true;
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("Automatic cartridge hand attachment failed: " + ex.Message);
return false;
}
}
}
}