using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.Json.Serialization;
using BodylogExtender;
using BodylogExtender.AvatarData;
using BodylogExtender.Managers;
using BodylogExtender.Util;
using BoneLib;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Bonelab.SaveData;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.SaveData;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSystem.Collections.Generic;
using LabFusion.Utilities;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "BodylogExtender", "1.0.0", "mash", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("BodylogExtender")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BodylogExtender")]
[assembly: AssemblyTitle("BodylogExtender")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace BodylogExtender
{
public class Mod : MelonMod
{
public static bool IsFusionLoaded;
public override void OnInitializeMelon()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
new Harmony("BodylogExtender").PatchAll();
IsFusionLoaded = MelonBase.FindMelon("LabFusion", "Lakatrazz") != null;
PresetManager.LoadPresetManager();
ModBoneMenu.CreateBoneMenu();
}
public override void OnUpdate()
{
BodyLogManager.Update();
}
}
public abstract class ModBoneMenu
{
public static void CreateBoneMenu()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: 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)
Page obj = Page.Root.CreatePage("BodyLog Extender", Color.magenta, 0, true);
obj.CreateInt("Preset Count", Color.magenta, (int)PresetManager.GetPresetCount(), 1, 0, 10, (Action<int>)delegate(int value)
{
PresetManager.SetPresetCount((uint)value);
});
obj.CreateFunction("Force Save", Color.green, (Action)PresetManager.SavePresetManager);
}
}
}
namespace BodylogExtender.Util
{
public class BodyLog
{
public const int BodylogAvatarCount = 6;
private readonly PullCordDevice _pullCordDevice;
private readonly MeshRenderer _meshRenderer;
public bool IsGrabbed;
public bool IsColorDirty;
public BodyLog(PullCordDevice pullCordDevice)
{
_pullCordDevice = pullCordDevice;
_meshRenderer = pullCordDevice.previewMeshRenderer;
}
public static AvatarPreset GetPreset()
{
List<string> favoriteAvatars_k__BackingField = DataManager.ActiveSave._PlayerSettings_k__BackingField._FavoriteAvatars_k__BackingField;
string[] array = new string[6];
for (int i = 0; i < favoriteAvatars_k__BackingField._size; i++)
{
array[i] = favoriteAvatars_k__BackingField._items[i];
}
return new AvatarPreset(array);
}
private static List<string> GetAvatarsNativeList(AvatarPreset preset)
{
List<string> val = new List<string>();
for (int i = 0; i < 6; i++)
{
val.Add(preset.Avatars[i]);
}
return val;
}
public static void SetPreset(AvatarPreset preset, BodyLog? bodyLog = null)
{
List<string> avatarsNativeList = GetAvatarsNativeList(preset);
DataManager.ActiveSave._PlayerSettings_k__BackingField._FavoriteAvatars_k__BackingField = avatarsNativeList;
DataManager.TrySaveActiveSave((SaveFlags)0);
bodyLog?.SyncToGameObject();
}
public void SetColor(Color color)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
((Renderer)_meshRenderer).material.color = color;
((Renderer)_meshRenderer).material.SetColor("_EmissionColor", color);
}
public bool IsValid()
{
return Object.op_Implicit((Object)(object)_pullCordDevice);
}
public void SyncToGameObject()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
_pullCordDevice.LoadFavoriteAvatars();
_pullCordDevice.UpdateAllPreviewMeshes();
_pullCordDevice.lastAvatarIndex = (_pullCordDevice.avatarIndex + 1) % 6;
_pullCordDevice.SetPreviewMesh(_pullCordDevice.avatarIndex);
IsColorDirty = true;
}
}
}
namespace BodylogExtender.Patches
{
[HarmonyPatch(typeof(PullCordDevice))]
public class BodyLogPatches
{
[HarmonyPrefix]
[HarmonyPatch("OnBallGripAttached")]
private static bool OnBallGripAttachedPrefix(PullCordDevice __instance)
{
BodyLogManager.OnBodyLogGrabbed(__instance);
return true;
}
[HarmonyPrefix]
[HarmonyPatch("OnBallGripDetached")]
private static bool OnBallGripDetachedPrefix(PullCordDevice __instance)
{
BodyLogManager.OnBodyLogReleased(__instance);
return true;
}
}
}
namespace BodylogExtender.Managers
{
public abstract class BodyLogManager
{
private static BodyLog? _activeBodyLog;
private static bool IsFusionLocalRig(RigManager rig)
{
return FusionPlayer.IsLocalPlayer(rig);
}
private static bool IsLocalPlayer(RigManager rig)
{
if (Mod.IsFusionLoaded)
{
return IsFusionLocalRig(rig);
}
return true;
}
public static void OnBodyLogGrabbed(PullCordDevice pullCordDevice)
{
if (IsLocalPlayer(pullCordDevice.rm))
{
if (_activeBodyLog == null || !_activeBodyLog.IsValid())
{
_activeBodyLog = new BodyLog(pullCordDevice);
BodyLog.SetPreset(PresetManager.GetActivePreset(), _activeBodyLog);
_activeBodyLog.IsGrabbed = true;
}
else if (!_activeBodyLog.IsGrabbed)
{
_activeBodyLog.IsGrabbed = true;
PresetManager.SetActivePreset(BodyLog.GetPreset());
}
}
}
public static void OnBodyLogReleased(PullCordDevice pullCordDevice)
{
if (IsLocalPlayer(pullCordDevice.rm) && _activeBodyLog != null && _activeBodyLog.IsValid() && _activeBodyLog.IsGrabbed)
{
_activeBodyLog.IsGrabbed = false;
PresetManager.SavePresetManager();
}
}
public static void Update()
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
if (_activeBodyLog != null && _activeBodyLog.IsValid() && _activeBodyLog.IsGrabbed)
{
if (_activeBodyLog.IsColorDirty)
{
_activeBodyLog.SetColor(PresetManager.GetPresetColor());
}
if (InputManager.IsSwitchPresetButtonDown())
{
PresetManager.SetActivePreset(BodyLog.GetPreset());
PresetManager.ToNextPreset();
BodyLog.SetPreset(PresetManager.GetActivePreset(), _activeBodyLog);
}
}
}
}
public abstract class InputManager
{
private static BaseController GetGrabbingController()
{
if (!PlayerRefs._Instance_k__BackingField._bodyVitals.bodyLogFlipped)
{
return Player.LeftController;
}
return Player.RightController;
}
public static bool IsSwitchPresetButtonDown()
{
return GetGrabbingController()._menuTap;
}
}
public static class PresetManager
{
private static readonly string FilePath = MelonEnvironment.UserDataDirectory + "/FavoriteAvatars.json";
private static PresetState _state = new PresetState();
public static void SetActivePreset(AvatarPreset preset)
{
_state.ActivePreset = preset;
}
public static Color GetPresetColor()
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
return Color.HSVToRGB(1f / (float)_state.Size * (float)_state.Index, 1f, 1f);
}
public static AvatarPreset GetActivePreset()
{
return _state.GetOrCreateActivePreset();
}
public static void ToNextPreset()
{
_state.Index = (_state.Index + 1) % _state.Size;
}
public static uint GetPresetCount()
{
return _state.Size;
}
public static void SetPresetCount(uint count)
{
_state.Size = count;
}
private static PresetState? LoadPresetState()
{
if (!File.Exists(FilePath))
{
return null;
}
try
{
return JsonSerializer.Deserialize<PresetState>(File.ReadAllText(FilePath));
}
catch (Exception ex)
{
MelonLogger.Error("Failed to load presets from file!", ex);
return null;
}
}
private static void SavePresetState(PresetState presetSaveData)
{
string contents = JsonSerializer.Serialize(presetSaveData);
File.WriteAllText(FilePath, contents);
}
public static void LoadPresetManager()
{
PresetState presetState = LoadPresetState();
if (presetState != null)
{
_state = presetState;
}
}
public static void SavePresetManager()
{
SavePresetState(_state);
}
}
}
namespace BodylogExtender.AvatarData
{
public class AvatarPreset
{
private const string FallbackAvatarBarcode = "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Strong";
private const int RandomAvatarListSize = 16;
private static readonly string[] RandomAvatarList = new string[16];
[JsonInclude]
public readonly string[] Avatars;
private static string GetRandomAvatarBarcode()
{
int num = Random.RandomRangeInt(0, 16);
return RandomAvatarList[num];
}
public AvatarPreset(string[] avatars)
{
if (avatars.Length != 6)
{
throw new Exception("Avatar list must have the same number of avatars.");
}
Avatars = avatars;
}
public void SetAvatar(int index, string barcode)
{
if (index < 0 || index >= Avatars.Length)
{
MelonLogger.Error("Avatar Index out of range: ", new object[1] { index });
}
else
{
Avatars[index] = barcode;
}
}
public static void PopulateRandomAvatarList()
{
List<AvatarCrate> crates = AssetWarehouse.Instance.GetCrates<AvatarCrate>((ICrateFilter<AvatarCrate>)null);
int num = crates._size / 16;
for (int i = 0; i < 16; i++)
{
RandomAvatarList[i] = ((Scannable)crates._items[i * num]).Barcode.ID;
}
}
}
public class PresetState
{
[JsonInclude]
public uint Size = 4u;
[JsonInclude]
public uint Index;
[JsonInclude]
public Dictionary<int, AvatarPreset> Presets = new Dictionary<int, AvatarPreset>();
[JsonIgnore]
public AvatarPreset ActivePreset
{
get
{
return Presets[(int)Index];
}
set
{
Presets[(int)Index] = value;
}
}
public AvatarPreset GetOrCreateActivePreset()
{
if (Presets.TryGetValue((int)Index, out AvatarPreset value))
{
return value;
}
AvatarPreset avatarPreset = new AvatarPreset(new string[6] { "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Strong", "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Strong", "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Strong", "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Strong", "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Strong", "fa534c5a83ee4ec6bd641fec424c4142.Avatar.Strong" });
Presets.Add((int)Index, avatarPreset);
return avatarPreset;
}
}
}