using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Interaction;
using LabFusion.Entities;
using LabFusion.Network;
using LabFusion.Player;
using MelonLoader;
using Microsoft.CodeAnalysis;
using NimbusImprover;
using NimbusImprover.ClipContainer;
using NimbusImprover.FusionIntegration;
using NimbusImprover.NimbusPatches;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "NimbusImprover", "1.0.0", "notnotnotswipez", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonOptionalDependencies(new string[] { "LabFusion" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("NimbusImprover")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("NimbusImprover")]
[assembly: AssemblyTitle("NimbusImprover")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 NimbusImprover
{
public class Core : MelonMod
{
public static float cachedFixedDeltaTime;
public override void OnInitializeMelon()
{
((MelonBase)this).LoggerInstance.Msg("Initialized.");
if (MelonBase.FindMelon("LabFusion", "Lakatrazz") != null)
{
try
{
FusionNimbus.AttemptRegister();
}
catch (Exception)
{
}
}
Hooking.OnLevelLoaded += delegate
{
cachedFixedDeltaTime = Time.fixedDeltaTime;
NimbusGunManager.ClearNimbusGunMemory();
};
}
public override void OnUpdate()
{
NimbusGunManager.Update();
}
public override void OnFixedUpdate()
{
NimbusGunManager.FixedUpdate();
}
}
public class NimbusGunManager
{
private static Dictionary<int, Tuple<FlyingGun, Hand>> flyingGuns = new Dictionary<int, Tuple<FlyingGun, Hand>>();
private static float lastLocalTimePressed = 0f;
public static Action<FlyingGun> OnClientNimbusUpdateClipActivate;
public static Action<FlyingGun> OnClientNimbusUpdateClipDeActivate;
private static Dictionary<int, Dictionary<int, EntityClipManager>> rigClipMarrowEntities = new Dictionary<int, Dictionary<int, EntityClipManager>>();
private static List<int> rigsInNoclip = new List<int>();
public static void MarkRigAsNoClip(RigManager rigManager, bool noclipped)
{
if (noclipped)
{
if (!rigsInNoclip.Contains(((Object)rigManager).GetInstanceID()))
{
rigsInNoclip.Add(((Object)rigManager).GetInstanceID());
}
}
else if (rigsInNoclip.Contains(((Object)rigManager).GetInstanceID()))
{
rigsInNoclip.Remove(((Object)rigManager).GetInstanceID());
UnClipRigAssociatedEntities(rigManager);
}
}
public static void ReUnCollideHands(RigManager rigManager)
{
MelonCoroutines.Start(WaitAndUnCollide(rigManager));
}
private static IEnumerator WaitAndUnCollide(RigManager rigManager)
{
for (int i = 0; i < 20; i++)
{
yield return null;
}
if (IsRigNoClipped(rigManager))
{
rigManager.physicsRig.leftHand.rb.detectCollisions = false;
rigManager.physicsRig.rightHand.rb.detectCollisions = false;
((Component)((Rig)rigManager.physicsRig).m_elbowLf).GetComponent<Rigidbody>().detectCollisions = false;
((Component)((Rig)rigManager.physicsRig).m_elbowRt).GetComponent<Rigidbody>().detectCollisions = false;
}
}
public static bool IsRigNoClipped(RigManager rigManager)
{
return rigsInNoclip.Contains(((Object)rigManager).GetInstanceID());
}
public static void AddLocalMarrowEntityToClip(RigManager rigManager, MarrowEntity marrowEntity)
{
if (Object.op_Implicit((Object)(object)marrowEntity) && !Object.op_Implicit((Object)(object)((Component)marrowEntity).GetComponentInParent<RigManager>()))
{
if (!rigClipMarrowEntities.ContainsKey(((Object)rigManager).GetInstanceID()))
{
rigClipMarrowEntities.Add(((Object)rigManager).GetInstanceID(), new Dictionary<int, EntityClipManager>());
}
Dictionary<int, EntityClipManager> dictionary = rigClipMarrowEntities[((Object)rigManager).GetInstanceID()];
if (!dictionary.ContainsKey(((Object)marrowEntity).GetInstanceID()))
{
dictionary.Add(((Object)marrowEntity).GetInstanceID(), new EntityClipManager(marrowEntity));
}
EntityClipManager entityClipManager = dictionary[((Object)marrowEntity).GetInstanceID()];
entityClipManager.ActivateNoClip();
}
}
public static void RemoveLocalMarrowEntityToClip(RigManager rigManager, MarrowEntity marrowEntity)
{
if (Object.op_Implicit((Object)(object)marrowEntity) && rigClipMarrowEntities.ContainsKey(((Object)rigManager).GetInstanceID()))
{
Dictionary<int, EntityClipManager> dictionary = rigClipMarrowEntities[((Object)rigManager).GetInstanceID()];
if (dictionary.ContainsKey(((Object)marrowEntity).GetInstanceID()))
{
EntityClipManager entityClipManager = dictionary[((Object)marrowEntity).GetInstanceID()];
entityClipManager.DisableNoClip();
dictionary.Remove(((Object)marrowEntity).GetInstanceID());
}
}
}
public static void UnClipRigAssociatedEntities(RigManager rigManager)
{
if (!rigClipMarrowEntities.ContainsKey(((Object)rigManager).GetInstanceID()))
{
return;
}
Dictionary<int, EntityClipManager> dictionary = rigClipMarrowEntities[((Object)rigManager).GetInstanceID()];
foreach (EntityClipManager value in dictionary.Values)
{
value.DisableNoClip();
}
dictionary.Clear();
rigClipMarrowEntities.Remove(((Object)rigManager).GetInstanceID());
}
public static void AttemptAddFlyingGun(FlyingGun flyingGun, Hand hand)
{
if (!flyingGuns.ContainsKey(((Object)flyingGun).GetInstanceID()))
{
flyingGun.canNoClip = false;
flyingGuns.Add(((Object)flyingGun).GetInstanceID(), new Tuple<FlyingGun, Hand>(flyingGun, hand));
}
}
public static void AttemptRemoveFlyingGun(FlyingGun flyingGun)
{
flyingGun.canNoClip = true;
flyingGuns.Remove(((Object)flyingGun).GetInstanceID());
}
public static void FixedUpdate()
{
NimbusUpdatePatch.PreventUpdate = false;
foreach (Tuple<FlyingGun, Hand> value in flyingGuns.Values)
{
if (!Object.op_Implicit((Object)(object)value.Item1))
{
continue;
}
bool noClipping = value.Item1._noClipping;
value.Item1.OnTriggerGripUpdate(value.Item2);
if (((Object)value.Item2.manager).GetInstanceID() != ((Object)Player.RigManager).GetInstanceID())
{
continue;
}
bool noClipping2 = value.Item1._noClipping;
if (noClipping != noClipping2)
{
if (noClipping2)
{
value.Item1.EnableNoClip();
}
else
{
value.Item1.DisableNoClip(value.Item2);
}
lastLocalTimePressed = Time.realtimeSinceStartup;
}
}
NimbusUpdatePatch.PreventUpdate = true;
}
public static void Update()
{
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
foreach (Tuple<FlyingGun, Hand> value in flyingGuns.Values)
{
if (!Object.op_Implicit((Object)(object)value.Item2) || ((Object)value.Item2.manager).GetInstanceID() != ((Object)Player.RigManager).GetInstanceID())
{
continue;
}
BaseController controller = value.Item2.Controller;
bool menuTap = controller.GetMenuTap();
value.Item1._smoothedDirection = value.Item1.firePoint.forward;
if (menuTap)
{
float realtimeSinceStartup = Time.realtimeSinceStartup;
if (realtimeSinceStartup - lastLocalTimePressed < Core.cachedFixedDeltaTime)
{
break;
}
lastLocalTimePressed = realtimeSinceStartup;
if (value.Item1._noClipping)
{
DeactivateNimbusClip(value.Item1);
}
else
{
ActivateNimbusClip(value.Item1);
}
}
}
}
private static void ActivateNimbusClip(FlyingGun flyingGun)
{
flyingGun.EnableNoClip();
flyingGun.sfx.Release();
OnClientNimbusUpdateClipActivate?.Invoke(flyingGun);
}
private static void DeactivateNimbusClip(FlyingGun flyingGun)
{
flyingGun.DisableNoClip(flyingGun.triggerGrip.GetHand());
flyingGun.sfx.Grab();
OnClientNimbusUpdateClipDeActivate?.Invoke(flyingGun);
}
public static void ClearNimbusGunMemory()
{
flyingGuns.Clear();
rigClipMarrowEntities.Clear();
rigsInNoclip.Clear();
}
}
}
namespace NimbusImprover.NimbusPatches
{
[HarmonyPatch(typeof(FlyingGun), "OnTriggerHandAttached")]
public class NumbusHandAttachPatch
{
public static void Postfix(FlyingGun __instance, Hand hand)
{
NimbusGunManager.AttemptAddFlyingGun(__instance, hand);
}
}
[HarmonyPatch(typeof(FlyingGun), "OnTriggerHandDetached")]
public class NumbusHandDetachPatch
{
public static void Postfix(FlyingGun __instance, Hand hand)
{
NimbusGunManager.AttemptRemoveFlyingGun(__instance);
}
}
[HarmonyPatch(typeof(FlyingGun), "OnTriggerGripUpdate")]
public class NimbusUpdatePatch
{
public static bool PreventUpdate = true;
public static bool Prefix(FlyingGun __instance, Hand hand)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Invalid comparison between Unknown and I4
if ((int)hand.handedness == 1 && hand.otherHand.HasAttachedObject() && Object.op_Implicit((Object)(object)hand.otherHand.m_CurrentAttachedGO.GetComponentInParent<FlyingGun>()))
{
return false;
}
if (PreventUpdate)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(FlyingGun), "EnableNoClip")]
public class OnFlyingGunClipEnable
{
public static void Postfix(FlyingGun __instance)
{
Hand hand = __instance.triggerGrip.GetHand();
RigManager manager = hand.manager;
NimbusGunManager.MarkRigAsNoClip(manager, noclipped: true);
if (hand.otherHand.HasAttachedObject())
{
NimbusGunManager.AddLocalMarrowEntityToClip(manager, hand.otherHand.m_CurrentAttachedGO.GetComponentInParent<MarrowEntity>());
}
}
}
[HarmonyPatch(typeof(FlyingGun), "DisableNoClip")]
public class OnFlyingGunClipDisable
{
public static void Postfix(FlyingGun __instance, Hand hand)
{
NimbusGunManager.MarkRigAsNoClip(hand.manager, noclipped: false);
}
}
}
namespace NimbusImprover.GripPatches
{
[HarmonyPatch(typeof(Grip), "OnAttachedToHand")]
public class GripAttachPatch
{
public static void Postfix(Grip __instance, Hand hand)
{
if (NimbusGunManager.IsRigNoClipped(hand.manager))
{
NimbusGunManager.AddLocalMarrowEntityToClip(hand.manager, ((Component)__instance).GetComponentInParent<MarrowEntity>());
NimbusGunManager.ReUnCollideHands(hand.manager);
}
}
}
[HarmonyPatch(typeof(Grip), "OnDetachedFromHand")]
public class GripDetachPatch
{
public static void Postfix(Grip __instance, Hand hand)
{
if (NimbusGunManager.IsRigNoClipped(hand.manager))
{
NimbusGunManager.RemoveLocalMarrowEntityToClip(hand.manager, ((Component)__instance).GetComponentInParent<MarrowEntity>());
NimbusGunManager.ReUnCollideHands(hand.manager);
}
}
}
}
namespace NimbusImprover.FusionIntegration
{
public class FusionNimbus
{
public static void AttemptRegister()
{
NimbusGunManager.OnClientNimbusUpdateClipActivate = (Action<FlyingGun>)Delegate.Combine(NimbusGunManager.OnClientNimbusUpdateClipActivate, (Action<FlyingGun>)delegate(FlyingGun flyingGun)
{
SendClipStatusUpdate(flyingGun);
});
NimbusGunManager.OnClientNimbusUpdateClipDeActivate = (Action<FlyingGun>)Delegate.Combine(NimbusGunManager.OnClientNimbusUpdateClipDeActivate, (Action<FlyingGun>)delegate(FlyingGun flyingGun)
{
SendClipStatusUpdate(flyingGun);
});
}
private static void SendClipStatusUpdate(FlyingGun flyingGun)
{
if (!NetworkInfo.HasServer)
{
return;
}
NetworkEntity val = FlyingGunExtender.Cache.Get(flyingGun);
if (val == null)
{
return;
}
FusionWriter val2 = FusionWriter.Create(4);
try
{
NimbusGunNoclipData val3 = NimbusGunNoclipData.Create(PlayerIdManager.LocalSmallId, val.Id, flyingGun._noClipping);
val2.Write<NimbusGunNoclipData>(val3);
FusionMessage val4 = FusionMessage.Create(NativeMessageTag.NimbusGunNoclip, val2);
try
{
MessageSender.SendToServer((NetworkChannel)0, val4);
}
finally
{
((IDisposable)val4)?.Dispose();
}
}
finally
{
((IDisposable)val2)?.Dispose();
}
}
}
}
namespace NimbusImprover.ClipContainer
{
public class EntityClipManager
{
private bool isClipped = false;
public MarrowEntity targetEntity;
public EntityClipManager(MarrowEntity marrowEntity)
{
targetEntity = marrowEntity;
}
public void ActivateNoClip()
{
if (!Object.op_Implicit((Object)(object)targetEntity) || isClipped)
{
return;
}
foreach (MarrowBody item in (Il2CppArrayBase<MarrowBody>)(object)targetEntity.Bodies)
{
if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item._rigidbody))
{
item._rigidbody.detectCollisions = false;
}
}
isClipped = true;
}
public void DisableNoClip()
{
if (!Object.op_Implicit((Object)(object)targetEntity) || !isClipped)
{
return;
}
foreach (MarrowBody item in (Il2CppArrayBase<MarrowBody>)(object)targetEntity.Bodies)
{
if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item._rigidbody))
{
item._rigidbody.detectCollisions = true;
}
}
isClipped = false;
}
}
}