using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using BoneLib.BoneMenu;
using HarmonyLib;
using HeadOffsetFixer;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.VRMK;
using Il2CppSystem;
using MelonLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
[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), "HeadOffsetFixer", "1.3.0", "notnotnotswipez", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonPriority(300)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("HeadOffsetFixer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HeadOffsetFixer")]
[assembly: AssemblyTitle("HeadOffsetFixer")]
[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 HeadOffsetFixer
{
public class Core : MelonMod
{
public static Avatar headlessAvatarClone;
public static Animator headlessAvatarCloneAnimator;
public static List<SafeBonePairing> safeBonePairings = new List<SafeBonePairing>();
public static List<SafeRendererPairing> safeRendererPairings = new List<SafeRendererPairing>();
public static List<Renderer> selfRenderers = new List<Renderer>();
public static List<Renderer> cloneAvatarRenderers = new List<Renderer>();
public static bool ignoreSpectator = true;
public static Camera lastBeginRenderCam;
public override void OnInitializeMelon()
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
RenderPipelineManager.beginCameraRendering += Action<ScriptableRenderContext, Camera>.op_Implicit((Action<ScriptableRenderContext, Camera>)delegate(ScriptableRenderContext ctx, Camera cam)
{
lastBeginRenderCam = cam;
CheckRenderLoop(cam);
});
Page val = Page.Root.CreatePage("HeadOffsetFixer", Color.green, 0, true);
val.CreateBool("Ignore Spectator Camera", Color.yellow, ignoreSpectator, (Action<bool>)delegate(bool b)
{
ignoreSpectator = b;
});
}
public static void CheckRenderLoop(Camera cam)
{
if (!Player.HandsExist || !Object.op_Implicit((Object)(object)Player.Avatar))
{
return;
}
if (((Object)cam).name.Equals("Headset") || (((Object)cam).name.Equals("Spectator Camera") && ignoreSpectator))
{
ToggleAvatarVisibility(selfRenderers, show: true);
if (Object.op_Implicit((Object)(object)headlessAvatarClone))
{
ToggleAvatarVisibility(cloneAvatarRenderers, show: false);
}
}
else if (Object.op_Implicit((Object)(object)headlessAvatarClone))
{
ToggleAvatarVisibility(selfRenderers, show: false);
ToggleAvatarVisibility(cloneAvatarRenderers, show: true);
}
else
{
ToggleAvatarVisibility(selfRenderers, show: true);
}
}
public static void EnforceVisibility(bool showClone)
{
if (!Player.HandsExist || !Object.op_Implicit((Object)(object)Player.Avatar))
{
return;
}
if (showClone)
{
if (Object.op_Implicit((Object)(object)headlessAvatarClone))
{
ToggleAvatarVisibility(selfRenderers, show: false);
ToggleAvatarVisibility(cloneAvatarRenderers, show: true);
}
else
{
ToggleAvatarVisibility(selfRenderers, show: true);
}
}
else
{
ToggleAvatarVisibility(selfRenderers, show: true);
if (Object.op_Implicit((Object)(object)headlessAvatarClone))
{
ToggleAvatarVisibility(cloneAvatarRenderers, show: false);
}
}
}
private static void ToggleAvatarVisibility(List<Renderer> renderers, bool show)
{
foreach (Renderer renderer in renderers)
{
renderer.forceRenderingOff = !show;
}
}
}
public struct SafeBonePairing
{
public Transform sourceBone;
public Transform destinationBone;
public void Copy()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
destinationBone.SetPositionAndRotation(sourceBone.position, sourceBone.rotation);
}
}
public struct SafeRendererPairing
{
public Renderer sourceRenderer;
public Renderer destinationRenderer;
public bool forceDisable;
public void Copy()
{
destinationRenderer.materials = sourceRenderer.materials;
if (forceDisable)
{
destinationRenderer.forceRenderingOff = true;
}
else
{
destinationRenderer.enabled = sourceRenderer.enabled && ((Component)sourceRenderer).gameObject.activeInHierarchy;
}
}
}
[HarmonyPatch(typeof(UniversalRenderPipeline), "RenderSingleCamera", new Type[]
{
typeof(ScriptableRenderContext),
typeof(Camera)
})]
public class RenderSingleCameraPatch
{
public static void Prefix(ScriptableRenderContext context, Camera camera)
{
Core.EnforceVisibility(showClone: true);
}
}
[HarmonyPatch(typeof(UniversalRenderPipeline), "RenderSingleCamera", new Type[]
{
typeof(ScriptableRenderContext),
typeof(Camera)
})]
public class RenderSingleCameraPatchPostfix
{
public static void Postfix(ScriptableRenderContext context, Camera camera)
{
Core.CheckRenderLoop(Core.lastBeginRenderCam);
}
}
[HarmonyPatch(typeof(PlayerAvatarArt), "UpdateAvatarHead")]
public class PlayerArtPatch
{
public static void Prefix(PlayerAvatarArt __instance)
{
if (((Object)((Rig)__instance._openCtrlRig).manager).GetInstanceID() != ((Object)Player.RigManager).GetInstanceID() || !Object.op_Implicit((Object)(object)Core.headlessAvatarCloneAnimator))
{
return;
}
foreach (SafeBonePairing safeBonePairing in Core.safeBonePairings)
{
safeBonePairing.Copy();
}
foreach (SafeRendererPairing safeRendererPairing in Core.safeRendererPairings)
{
safeRendererPairing.Copy();
}
}
}
[HarmonyPatch(typeof(ArtRig), "SetArtOutputAvatar")]
public class RigmanagerAvatarSwitchEventPatch
{
public static void Postfix(ArtRig __instance, PhysicsRig inRig, Avatar avatar)
{
if (Object.op_Implicit((Object)(object)Player.RigManager))
{
if (((Object)((Rig)inRig).manager).GetInstanceID() == ((Object)Player.RigManager).GetInstanceID())
{
if (Object.op_Implicit((Object)(object)Core.headlessAvatarClone))
{
Object.DestroyImmediate((Object)(object)((Component)Core.headlessAvatarClone).gameObject);
}
Core.selfRenderers.Clear();
Core.cloneAvatarRenderers.Clear();
MelonCoroutines.Start(WaitForRigToUpdateAvatar(((Rig)inRig).manager));
}
}
else
{
Core.selfRenderers.Clear();
Core.cloneAvatarRenderers.Clear();
}
}
private static IEnumerator WaitForRigToUpdateAvatar(RigManager manager)
{
for (int i = 0; i < 3; i++)
{
yield return null;
}
if (!Object.op_Implicit((Object)(object)manager.avatar))
{
yield break;
}
foreach (Renderer selfRenderer in ((Component)manager.avatar).GetComponentsInChildren<Renderer>(true))
{
Core.selfRenderers.Add(selfRenderer);
}
GameObject disabledObject = new GameObject("DISABLED CONTAINER");
disabledObject.SetActive(false);
GameObject headlessCloneObject = Object.Instantiate<GameObject>(((Component)manager.avatar).gameObject, disabledObject.transform);
CleanClone(headlessCloneObject);
headlessCloneObject.transform.parent = null;
Object.Destroy((Object)(object)disabledObject);
Core.headlessAvatarClone = headlessCloneObject.GetComponentInChildren<Avatar>();
Core.headlessAvatarCloneAnimator = Core.headlessAvatarClone.animator;
foreach (SkinnedMeshRenderer hairMesh in (Il2CppArrayBase<SkinnedMeshRenderer>)(object)Core.headlessAvatarClone.hairMeshes)
{
((Renderer)hairMesh).shadowCastingMode = (ShadowCastingMode)1;
}
foreach (Renderer cloneRenderer in ((Component)Core.headlessAvatarClone).GetComponentsInChildren<Renderer>(true))
{
Core.cloneAvatarRenderers.Add(cloneRenderer);
}
SaveAllValidBones(manager.avatar.animator, Core.headlessAvatarCloneAnimator);
SaveAllValidRenderers(((Component)manager.avatar).gameObject, headlessCloneObject);
((Object)headlessCloneObject).name = "HEADFIX DISPLAY CLONE";
}
private static void CleanClone(GameObject cloneAvatar)
{
foreach (MonoBehaviour componentsInChild in cloneAvatar.GetComponentsInChildren<MonoBehaviour>(true))
{
if (!Object.op_Implicit((Object)(object)((Il2CppObjectBase)componentsInChild).TryCast<Avatar>()))
{
Object.DestroyImmediate((Object)(object)componentsInChild);
}
}
foreach (ConfigurableJoint componentsInChild2 in cloneAvatar.GetComponentsInChildren<ConfigurableJoint>(true))
{
Object.DestroyImmediate((Object)(object)componentsInChild2);
}
foreach (Collider componentsInChild3 in cloneAvatar.GetComponentsInChildren<Collider>(true))
{
Object.DestroyImmediate((Object)(object)componentsInChild3);
}
foreach (Rigidbody componentsInChild4 in cloneAvatar.GetComponentsInChildren<Rigidbody>(true))
{
Object.DestroyImmediate((Object)(object)componentsInChild4);
}
foreach (InteractableHost componentsInChild5 in cloneAvatar.GetComponentsInChildren<InteractableHost>(true))
{
Object.DestroyImmediate((Object)(object)componentsInChild5);
}
}
private static void SaveAllValidBones(Animator source, Animator destination)
{
Core.safeBonePairings.Clear();
Transform[] allBones = GetAllBones(((Component)source).gameObject);
Transform[] allBones2 = GetAllBones(((Component)destination).gameObject);
for (int i = 0; i < allBones.Length; i++)
{
Core.safeBonePairings.Add(new SafeBonePairing
{
sourceBone = allBones[i],
destinationBone = allBones2[i]
});
allBones2[i].parent = ((Component)destination).gameObject.transform;
}
}
private static Transform[] GetAllBones(GameObject root)
{
Dictionary<int, Transform> dictionary = new Dictionary<int, Transform>();
foreach (SkinnedMeshRenderer componentsInChild in root.GetComponentsInChildren<SkinnedMeshRenderer>(true))
{
Il2CppReferenceArray<Transform> bones = componentsInChild.bones;
foreach (Transform item in (Il2CppArrayBase<Transform>)(object)bones)
{
if (!dictionary.ContainsKey(((Object)item).GetInstanceID()))
{
dictionary.Add(((Object)item).GetInstanceID(), item);
}
}
}
return dictionary.Values.ToArray();
}
private static void SaveAllValidRenderers(GameObject source, GameObject destination)
{
Core.safeRendererPairings.Clear();
Il2CppArrayBase<Renderer> componentsInChildren = source.GetComponentsInChildren<Renderer>(true);
Il2CppArrayBase<Renderer> componentsInChildren2 = destination.GetComponentsInChildren<Renderer>(true);
List<Transform> list = new List<Transform>();
for (int i = 0; i < componentsInChildren.Length; i++)
{
bool forceDisable = false;
Renderer val = componentsInChildren2[i];
if (Object.op_Implicit((Object)(object)val.material) && ((Object)val.material.shader).name == "SLZ/Icon Billboard")
{
forceDisable = true;
}
Core.safeRendererPairings.Add(new SafeRendererPairing
{
sourceRenderer = componentsInChildren[i],
destinationRenderer = componentsInChildren2[i],
forceDisable = forceDisable
});
((Component)componentsInChildren2[i]).gameObject.transform.parent = destination.transform;
((Component)componentsInChildren2[i]).gameObject.SetActive(true);
list.Add(((Component)componentsInChildren2[i]).gameObject.transform);
}
}
}
}