Decompiled source of Fusion v1.12.2
Mods/LabFusion.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers; using System.Buffers.Binary; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Net; using System.Net.Http; using System.Net.NetworkInformation; using System.Net.Security; using System.Net.Sockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; using GroovyCodecs.G711.aLaw; using HarmonyLib; using Il2Cpp; using Il2CppCysharp.Threading.Tasks; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.InteropTypes.Fields; using Il2CppSLZ.Bonelab; using Il2CppSLZ.Data; using Il2CppSLZ.Interaction; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.AI; using Il2CppSLZ.Marrow.Audio; using Il2CppSLZ.Marrow.Circuits; using Il2CppSLZ.Marrow.Combat; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.Forklift; using Il2CppSLZ.Marrow.Forklift.Model; using Il2CppSLZ.Marrow.Input; using Il2CppSLZ.Marrow.Interaction; using Il2CppSLZ.Marrow.Pool; using Il2CppSLZ.Marrow.PuppetMasta; using Il2CppSLZ.Marrow.SceneStreaming; using Il2CppSLZ.Marrow.Utilities; using Il2CppSLZ.Marrow.VFX; using Il2CppSLZ.Marrow.VoidLogic; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSLZ.Marrow.Zones; using Il2CppSLZ.Props; using Il2CppSLZ.UI; using Il2CppSLZ.VRMK; using Il2CppSteamworks; using Il2CppSystem; using Il2CppSystem.Collections; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using Il2CppUltEvents; using LabFusion; using LabFusion.Audio; using LabFusion.Bonelab; using LabFusion.Bonelab.Extenders; using LabFusion.Bonelab.Messages; using LabFusion.Bonelab.Patching; using LabFusion.Bonelab.Scene; using LabFusion.Data; using LabFusion.Data.Serializables; using LabFusion.Downloading; using LabFusion.Downloading.ModIO; using LabFusion.Entities; using LabFusion.Exceptions; using LabFusion.Extensions; using LabFusion.Grabbables; using LabFusion.Marrow; using LabFusion.Marrow.Circuits; using LabFusion.Marrow.Combat; using LabFusion.Marrow.Extenders; using LabFusion.Marrow.Extensions; using LabFusion.Marrow.Integration; using LabFusion.Marrow.Messages; using LabFusion.Marrow.Patching; using LabFusion.Marrow.Pool; using LabFusion.Marrow.Proxies; using LabFusion.Marrow.Scene; using LabFusion.Marrow.Serialization; using LabFusion.Marrow.Zones; using LabFusion.Math; using LabFusion.Menu; using LabFusion.Menu.Data; using LabFusion.Menu.Gamemodes; using LabFusion.MonoBehaviours; using LabFusion.Network; using LabFusion.Network.Proxy; using LabFusion.Network.Serialization; using LabFusion.Patching; using LabFusion.Player; using LabFusion.Preferences; using LabFusion.Preferences.Client; using LabFusion.Preferences.Server; using LabFusion.RPC; using LabFusion.Representation; using LabFusion.SDK; using LabFusion.SDK.Achievements; using LabFusion.SDK.Cosmetics; using LabFusion.SDK.Extenders; using LabFusion.SDK.Gamemodes; using LabFusion.SDK.Lobbies; using LabFusion.SDK.Messages; using LabFusion.SDK.Metadata; using LabFusion.SDK.Modules; using LabFusion.SDK.MonoBehaviours; using LabFusion.SDK.Points; using LabFusion.SDK.Scene; using LabFusion.SDK.Triggers; using LabFusion.Safety; using LabFusion.Scene; using LabFusion.Senders; using LabFusion.UI; using LabFusion.UI.Popups; using LabFusion.Utilities; using LabFusion.Voice; using LabFusion.Voice.Unity; using LabFusion.XML; using LiteNetLib; using LiteNetLib.Layers; using LiteNetLib.Utils; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Linq; using Steamworks; using Steamworks.Data; using Steamworks.Ugc; using UnityEngine; using UnityEngine.Audio; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.Video; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("LabFusion")] [assembly: AssemblyFileVersion("1.12.2")] [assembly: MelonInfo(typeof(FusionMod), "LabFusion", "1.12.2", "Lakatrazz", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: MelonPriority(-10000)] [assembly: MelonOptionalDependencies(new string[] { "Il2CppFacepunch.Steamworks.Win64" })] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.12.2.0")] [module: UnverifiableCode] 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 LabFusion { [StructLayout(LayoutKind.Sequential, Size = 1)] public struct FusionVersion { public const byte VersionMajor = 1; public const byte VersionMinor = 12; public const short VersionPatch = 2; public const string VersionString = "1.12.2"; } public class FusionMod : MelonMod { public const string ModName = "LabFusion"; public const string ModAuthor = "Lakatrazz"; public const string GameDeveloper = "Stress Level Zero"; public const string GameName = "BONELAB"; public static readonly Version Version = new Version(1, 12, 2); private static bool _hasAutoUpdater = false; private static int _nextSyncableSendRate = 1; public static string Changelog { get; internal set; } = null; public static string[] Credits { get; internal set; } = null; public static FusionMod Instance { get; private set; } public static Assembly FusionAssembly { get; private set; } public override void OnEarlyInitializeMelon() { Instance = this; FusionAssembly = ((MelonBase)this).MelonAssembly.Assembly; ModDownloadManager.DeleteTemporaryDirectories(); PersistentData.OnPathInitialize(); SteamAPILoader.OnLoadSteamAPI(); PDController.OnInitializeMelon(); PointItemManager.HookEvents(); RpcManager.OnInitialize(); } public override void OnInitializeMelon() { FusionFileLoader.OnInitializeMelon(); ListLoader.OnInitializeMelon(); LocalPlayer.OnInitializeMelon(); VoiceSourceManager.OnInitializeMelon(); InitializeBaseModules(); NativeMessageHandler.RegisterHandlersFromAssembly(FusionAssembly); GrabGroupHandler.RegisterHandlersFromAssembly(FusionAssembly); NetworkLayer.RegisterLayersFromAssembly(FusionAssembly); GamemodeRegistration.LoadGamemodes(FusionAssembly); PointItemManager.LoadItems(FusionAssembly); AchievementManager.LoadAchievements(FusionAssembly); RpcManager.LoadRpcs(FusionAssembly); EntityComponentManager.LoadComponents(FusionAssembly); LobbyFilterManager.LoadBuiltInFilters(); NetworkEntityManager.OnInitializeManager(); NetworkPlayerManager.OnInitializeManager(); PopupManager.OnInitializeMelon(); GamemodeManager.OnInitializeMelon(); GamemodeConditionsChecker.OnInitializeMelon(); GamemodeRoundManager.OnInitializeMelon(); AssetWarehouse.OnReady(Action.op_Implicit((Action)delegate { CosmeticLoader.OnAssetWarehouseReady(); })); FusionPreferences.OnInitializePreferences(); FusionPermissions.OnInitializeMelon(); LobbyInfoManager.OnInitialize(); MenuCreator.OnInitializeMelon(); FusionSceneManager.Internal_OnInitializeMelon(); MultiplayerHooking.OnLoadingBegin += OnLoadingBegin; NetworkSceneManager.OnInitializeMelon(); NetworkLayerManager.OnInitializeMelon(); } private static void InitializeBaseModules() { ModuleManager.RegisterModule<SDKModule>(); ModuleManager.RegisterModule<MarrowModule>(); ModuleManager.RegisterModule<BonelabModule>(); } public override void OnLateInitializeMelon() { PersistentAssetCreator.OnLateInitializeMelon(); PlayerAdditionsHelper.OnInitializeMelon(); _hasAutoUpdater = MelonTypeBase<MelonPlugin>.RegisteredMelons.Any((MelonPlugin p) => ((MelonBase)p).Info.Name.Contains("LabFusion Updater")); if (!_hasAutoUpdater) { Notifier.Send(new Notification { SaveToMenu = false, ShowPopup = true, Message = "You do not have the Fusion AutoUpdater installed in your plugins folder!\nIt is recommended to install it in order to stay up to date.", Type = NotificationType.WARNING }); } } public override void OnDeinitializeMelon() { NetworkLayerManager.LogOut(); FusionFileLoader.OnDeinitializeMelon(); PointItemManager.UnhookEvents(); PlayerAdditionsHelper.OnDeinitializeMelon(); SteamAPILoader.OnFreeSteamAPI(); } public override void OnPreferencesLoaded() { FusionPreferences.OnPreferencesLoaded(); } public static void OnMainSceneInitialized() { _ = ((Scannable)FusionSceneManager.Level).Title; NetworkEntityManager.OnCleanupIds(); RigData.OnCacheRigInfo(); PersistentAssetCreator.OnMainSceneInitialized(); ConstrainerUtilities.OnMainSceneInitialized(); MultiplayerHooking.InvokeOnMainSceneInitialized(); FusionPlayer.OnMainSceneInitialized(); } public static void OnMainSceneInitializeDelayed() { if (RigData.HasPlayer) { ((Il2CppObjectBase)RigData.Refs.RigManager.ControllerRig).TryCast<OpenControllerRig>().quickmenuEnabled = true; PlayerRefs.Instance.PlayerBodyVitals.quickmenuEnabled = true; MenuCreator.CreateMenu(); } } private void OnLoadingBegin() { ModIOThumbnailDownloader.ClearCache(); } public override void OnUpdate() { NetworkInfo.BytesDown = 0; NetworkInfo.BytesUp = 0; ModIODownloader.UpdateQueue(); TimeUtilities.OnEarlyUpdate(); FusionSceneManager.Internal_UpdateScene(); PopupManager.OnUpdate(); float deltaTime = TimeUtilities.DeltaTime; NetworkPlayerManager.OnUpdate(deltaTime); if (TimeUtilities.IsMatchingFrame(_nextSyncableSendRate)) { int bytesUp = NetworkInfo.BytesUp; NetworkEntityManager.OnUpdate(deltaTime); _nextSyncableSendRate = SendRateTable.GetObjectSendRate(NetworkInfo.BytesUp - bytesUp); } FusionPlayer.OnUpdate(); VoiceHelper.OnVoiceChatUpdate(); InternalLayerHelpers.OnUpdateLayer(); MultiplayerHooking.InvokeOnUpdate(); GamemodeManager.OnUpdate(); DelayUtilities.OnProcessDelays(); } public override void OnFixedUpdate() { TimeUtilities.OnEarlyFixedUpdate(); LocalPlayer.OnFixedUpdate(); PDController.OnFixedUpdate(); float fixedDeltaTime = TimeUtilities.FixedDeltaTime; NetworkPlayerManager.OnFixedUpdate(fixedDeltaTime); NetworkEntityManager.OnFixedUpdate(fixedDeltaTime); MultiplayerHooking.InvokeOnFixedUpdate(); GamemodeManager.OnFixedUpdate(); } public override void OnLateUpdate() { float deltaTime = TimeUtilities.DeltaTime; NetworkPlayerManager.OnLateUpdate(deltaTime); NetworkEntityManager.OnLateUpdate(deltaTime); InternalLayerHelpers.OnLateUpdateLayer(); MultiplayerHooking.InvokeOnLateUpdate(); GamemodeManager.OnLateUpdate(); } } } namespace LabFusion.Voice { public interface IVoiceManager { List<IVoiceSpeaker> VoiceSpeakers { get; } bool CanTalk { get; } bool CanHear { get; } string[] InputDevices { get; } IVoiceSpeaker GetSpeaker(PlayerID id); void RemoveSpeaker(PlayerID id); IVoiceReceiver GetReceiver(); void Enable(); void Disable(); void UpdateManager(); void ClearManager(); } public abstract class VoiceManager : IVoiceManager { protected List<IVoiceSpeaker> _voiceSpeakers = new List<IVoiceSpeaker>(); private IVoiceReceiver _receiver; private bool _hasDisabledVoice = true; public List<IVoiceSpeaker> VoiceSpeakers => _voiceSpeakers; public virtual bool CanTalk => true; public virtual bool CanHear => true; public virtual string[] InputDevices => Array.Empty<string>(); public void Enable() { _receiver = OnCreateReceiverOrDefault(); _receiver?.Enable(); } public void Disable() { if (_receiver != null) { _receiver.Disable(); _receiver = null; } ClearManager(); } protected bool TryGetSpeaker(PlayerID id, out IVoiceSpeaker speaker) { speaker = null; for (int i = 0; i < VoiceSpeakers.Count; i++) { IVoiceSpeaker voiceSpeaker = VoiceSpeakers[i]; if (voiceSpeaker.ID == id) { speaker = voiceSpeaker; return true; } } return false; } protected abstract IVoiceSpeaker OnCreateSpeaker(PlayerID id); protected abstract IVoiceReceiver OnCreateReceiverOrDefault(); public IVoiceSpeaker GetSpeaker(PlayerID id) { if (TryGetSpeaker(id, out var speaker)) { return speaker; } IVoiceSpeaker voiceSpeaker = OnCreateSpeaker(id); VoiceSpeakers.Add(voiceSpeaker); return voiceSpeaker; } public IVoiceReceiver GetReceiver() { return _receiver; } public void UpdateManager() { UpdateSpeakers(); UpdateReceiver(); } private void UpdateSpeakers() { for (int i = 0; i < VoiceSpeakers.Count; i++) { VoiceSpeakers[i].Update(); } } private void UpdateReceiver() { if (_receiver != null && CanTalk) { if (NetworkInfo.HasServer && !VoiceInfo.IsMuted) { _receiver.UpdateVoice(enabled: true); _hasDisabledVoice = false; } else if (!_hasDisabledVoice) { _receiver.UpdateVoice(enabled: false); _hasDisabledVoice = true; } if (_receiver.HasVoiceActivity()) { PlayerSender.SendPlayerVoiceChat(_receiver.GetEncodedData()); } } } public void RemoveSpeaker(PlayerID id) { IVoiceSpeaker voiceSpeaker = null; foreach (IVoiceSpeaker voiceSpeaker2 in VoiceSpeakers) { if (voiceSpeaker2.ID == id) { voiceSpeaker = voiceSpeaker2; break; } } if (voiceSpeaker != null) { voiceSpeaker.Cleanup(); _voiceSpeakers.Remove(voiceSpeaker); } } public void ClearManager() { foreach (IVoiceSpeaker voiceSpeaker in VoiceSpeakers) { voiceSpeaker.Cleanup(); } _voiceSpeakers.Clear(); } } public interface IVoiceReceiver { float GetVoiceAmplitude(); bool HasVoiceActivity(); byte[] GetEncodedData(); void UpdateVoice(bool enabled); void Enable(); void Disable(); } public interface IVoiceSpeaker { PlayerID ID { get; } float Volume { get; set; } float Amplitude { get; set; } void OnVoiceDataReceived(byte[] data); void Update(); void Cleanup(); } public abstract class VoiceSpeaker : IVoiceSpeaker { protected PlayerID _id; protected float _volume = 1f; public PlayerID ID => _id; public float Volume { get { return _volume; } set { _volume = value; } } public abstract float Amplitude { get; set; } public virtual void Update() { } public abstract void OnVoiceDataReceived(byte[] data); public abstract void Cleanup(); } public class JawFlapper { public const float MaxAngle = 40f; private float _voiceLoudness; public float GetAngle() { return _voiceLoudness * 40f; } public void ClearJaw() { _voiceLoudness = 0f; } public void UpdateJaw(float amplitude, float deltaTime) { float b = ManagedMathf.Clamp01(amplitude * 2f); _voiceLoudness = ManagedMathf.Lerp(_voiceLoudness, b, Smoothing.CalculateDecay(12f, deltaTime)); } } public static class VoiceConverter { public static readonly ALawEncoder G711Encoder = new ALawEncoder(); public static readonly ALawDecoder G711Decoder = new ALawDecoder(); public static void CopySamples(float[] from, short[] to, int sampleCount) { for (int i = 0; i < sampleCount; i++) { to[i] = ConvertSample(from[i]); } } public static void CopySamples(short[] from, float[] to, int sampleCount) { for (int i = 0; i < sampleCount; i++) { to[i] = ConvertSample(from[i]); } } public static short ConvertSample(float sample) { return (short)(sample * 32767f); } public static float ConvertSample(short sample) { return (float)sample / 32767f; } public static byte[] Encode(short[] samples) { return Compress(G711Encoder.Process(samples)); } public static short[] Decode(byte[] bytes) { return G711Decoder.Process(Decompress(bytes)); } public static byte[] Compress(byte[] data) { using MemoryStream memoryStream = new MemoryStream(); using DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionLevel.SmallestSize); deflateStream.Write(data, 0, data.Length); deflateStream.Close(); return memoryStream.ToArray(); } public static byte[] Decompress(byte[] data) { using MemoryStream stream = new MemoryStream(data); using DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); deflateStream.CopyTo(memoryStream); return memoryStream.ToArray(); } } public static class VoiceHelper { public static void OnVoiceChatUpdate() { VoiceInfo.VoiceManager?.UpdateManager(); } public static void OnVoiceDataReceived(PlayerID player, byte[] data) { if (!VoiceInfo.IsDeafened) { (VoiceInfo.VoiceManager?.GetSpeaker(player))?.OnVoiceDataReceived(data); } } } public static class VoiceInfo { public static IVoiceManager VoiceManager => NetworkLayerManager.Layer?.VoiceManager; public static bool CanTalk => (VoiceManager?.CanTalk).GetValueOrDefault(); public static bool CanHear => (VoiceManager?.CanHear).GetValueOrDefault(); public static string[] InputDevices { get { if (VoiceManager == null) { return Array.Empty<string>(); } return VoiceManager.InputDevices; } } public static bool ShowMuteIndicator { get { if (NetworkInfo.HasServer && ClientSettings.VoiceChat.Muted.Value) { return ClientSettings.VoiceChat.MutedIndicator.Value; } return false; } } public static float VoiceAmplitude => (VoiceManager?.GetReceiver()?.GetVoiceAmplitude()).GetValueOrDefault(); public static bool HasVoiceActivity => (VoiceManager?.GetReceiver()?.HasVoiceActivity()).GetValueOrDefault(); public static bool IsMuted { get { if (!ClientSettings.VoiceChat.Muted.Value) { return IsDeafened; } return true; } } public static bool IsDeafened { get { if (FusionSceneManager.IsLoading()) { return true; } if (!ClientSettings.VoiceChat.Deafened.Value) { return !ServerVoiceEnabled; } return true; } } public static bool ServerVoiceEnabled => LobbyInfoManager.LobbyInfo.VoiceChat; } [RegisterTypeInIl2Cpp] public class VoiceSource : MonoBehaviour { private bool _overrideFilter; private bool _muted; private bool _receivingInput; private float _timeSinceInput; private bool _wasPlaying; [HideFromIl2Cpp] public AudioSource AudioSource { get; private set; } [HideFromIl2Cpp] public AudioStreamFilter StreamFilter { get; private set; } public bool OverrideFilter { get { return _overrideFilter; } set { if (_overrideFilter != value) { _overrideFilter = value; ((Behaviour)StreamFilter).enabled = Playing && !value; } } } [HideFromIl2Cpp] public float Amplitude { get; set; } public bool Muted { get { return _muted; } set { if (_muted != value) { _muted = value; ProcessPlaying(); } } } public bool ReceivingInput { get { return _receivingInput; } set { if (_receivingInput != value) { _receivingInput = value; _timeSinceInput = 0f; ProcessPlaying(); } } } public float TimeSinceInput => _timeSinceInput; public bool Playing { get { if (ReceivingInput) { return !Muted; } return false; } } public int ID { get; set; } = -1; [HideFromIl2Cpp] public static event Action<VoiceSource> OnVoiceEnabled; [HideFromIl2Cpp] public static event Action<VoiceSource> OnVoiceDisabled; public VoiceSource(IntPtr intPtr) : base(intPtr) { } private void Awake() { GetAudioSource(); StopSources(); } private void OnEnable() { VoiceSource.OnVoiceEnabled?.Invoke(this); ReceivingInput = false; ((Behaviour)StreamFilter).enabled = true; ((Behaviour)StreamFilter).enabled = false; } private void OnDisable() { VoiceSource.OnVoiceDisabled?.Invoke(this); ReceivingInput = false; ((Behaviour)StreamFilter).enabled = false; } private void Update() { if (Playing) { if (StreamFilter.ReadingQueue.Count <= 0) { _timeSinceInput += Time.deltaTime; } if (_timeSinceInput > 1f) { ReceivingInput = false; } } } [HideFromIl2Cpp] private void ProcessPlaying() { if (_wasPlaying != Playing) { _wasPlaying = Playing; if (Playing) { PlaySources(); } else { StopSources(); } } } private void PlaySources() { ((Behaviour)StreamFilter).enabled = !OverrideFilter; AudioSource.Play(); Amplitude = 0f; } private void StopSources() { AudioSource.Stop(); ((Behaviour)StreamFilter).enabled = false; StreamFilter.ReadingQueue.Clear(); Amplitude = 0f; } [HideFromIl2Cpp] private void GetAudioSource() { AudioSource component = ((Component)this).GetComponent<AudioSource>(); if ((Object)(object)component != (Object)null) { AudioSource = component; } else { AudioSource = CreateAudioSource(); } SetSourceSettings(); } [HideFromIl2Cpp] private AudioSource CreateAudioSource() { AudioSource obj = ((Component)this).gameObject.AddComponent<AudioSource>(); obj.volume = 1f; obj.spatialBlend = 1f; obj.dopplerLevel = 0.5f; obj.spread = 60f; return obj; } [HideFromIl2Cpp] private void SetSourceSettings() { AudioSource.loop = true; AudioSource.playOnAwake = false; AudioSource.outputAudioMixerGroup = null; StreamFilter = ((Component)this).gameObject.AddComponent<AudioStreamFilter>(); AudioSource.clip = AudioInfo.CreateToneClip(); } } public static class VoiceSourceManager { public static List<VoiceSource> ActiveVoices { get; } = new List<VoiceSource>(); public static IEnumerable<VoiceSource> GetVoicesByID(int id) { return ActiveVoices.Where((VoiceSource voice) => voice.ID == id); } public static void EnqueueSample(IEnumerable<VoiceSource> sources, float sample) { foreach (VoiceSource source in sources) { try { source.StreamFilter.Enqueue(sample); } catch (Exception e) { FusionLogger.LogException("enqueueing VoiceSource sample", e); } } } public static void SetAmplitude(IEnumerable<VoiceSource> sources, float amplitude) { foreach (VoiceSource source in sources) { try { source.ReceivingInput = true; source.Amplitude = amplitude; } catch (Exception e) { FusionLogger.LogException("setting VoiceSource amplitude", e); } } } public static VoiceSource CreateVoiceSource(int id) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown return CreateVoiceSource(new GameObject($"Voice Source {id}"), id); } public static VoiceSource CreateVoiceSource(GameObject gameObject, int id) { VoiceSource voiceSource = gameObject.AddComponent<VoiceSource>(); voiceSource.ID = id; return voiceSource; } internal static void OnInitializeMelon() { VoiceSource.OnVoiceEnabled += OnVoiceEnabled; VoiceSource.OnVoiceDisabled += OnVoiceDisabled; } private static void OnVoiceEnabled(VoiceSource source) { ActiveVoices.Add(source); } private static void OnVoiceDisabled(VoiceSource source) { ActiveVoices.RemoveAll((VoiceSource s) => (Object)(object)s == (Object)(object)source); } } public static class VoiceVolume { public const float DefaultSampleMultiplier = 10f; public const float MinimumVoiceVolume = 0.3f; public const float SilencingVolume = 0.1f; public const float TalkTimeoutTime = 1f; public static float GetVolumeMultiplier() { float num = Audio3dManager.audio_GlobalVolume * 0.1f; float num2 = Audio3dManager.audio_SFXVolume * 0.1f; float value = ClientSettings.VoiceChat.GlobalVolume.Value; return num * num2 * value; } } } namespace LabFusion.Voice.Unity { public static class UnityVoice { public const int ClipLength = 1; private static bool _hasMicrophones; private static bool _checkedForMic; private static bool CheckForMicrophone() { try { _ = ((Il2CppArrayBase<string>)(object)Microphone.devices)[0]; return true; } catch { return false; } } public static bool IsSupported() { if (!_checkedForMic) { _hasMicrophones = CheckForMicrophone(); _checkedForMic = true; } return _hasMicrophones; } } public sealed class UnityVoiceManager : VoiceManager { public override bool CanTalk { get { if (!UnityVoice.IsSupported()) { return false; } return true; } } public override string[] InputDevices { get { if (!UnityVoice.IsSupported()) { return Array.Empty<string>(); } return Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)Microphone.devices); } } protected override IVoiceReceiver OnCreateReceiverOrDefault() { return new UnityVoiceReceiver(); } protected override IVoiceSpeaker OnCreateSpeaker(PlayerID id) { return new UnityVoiceSpeaker(id); } } public sealed class UnityVoiceReceiver : IVoiceReceiver { private static readonly float[] SampleBuffer = new float[AudioInfo.OutputSampleRate]; private byte[] _encodedData; private bool _hasVoiceActivity; private AudioClip _voiceClip; private int _lastSample; private float _amplitude; private float _lastTalkTime; private bool _loopedData; public float GetVoiceAmplitude() { return _amplitude; } public byte[] GetEncodedData() { return _encodedData; } public bool HasVoiceActivity() { return _hasVoiceActivity; } public static string GetValidMicrophoneName() { return ClientSettings.VoiceChat.InputDevice.Value; } private void ClearData() { _encodedData = null; _hasVoiceActivity = false; _amplitude = 0f; } public void UpdateVoice(bool enabled) { if (!UnityVoice.IsSupported()) { ClearData(); return; } string validMicrophoneName = GetValidMicrophoneName(); if (Microphone.GetMicrophoneDeviceIDFromName(validMicrophoneName) == -1) { ClearData(); return; } bool flag = Microphone.IsRecording(validMicrophoneName); if (enabled && !flag) { _voiceClip = Microphone.Start(validMicrophoneName, true, 1, AudioInfo.OutputSampleRate); } else if (!enabled && flag) { Microphone.End(validMicrophoneName); } if (!enabled || (Object)(object)_voiceClip == (Object)null) { ClearData(); return; } int num = Microphone.GetPosition(validMicrophoneName); if (num < _lastSample) { _loopedData = true; num = AudioInfo.OutputSampleRate; } int num2 = num - _lastSample; if (num2 <= 0) { _hasVoiceActivity = false; return; } Il2CppStructArray<float> val = new Il2CppStructArray<float>((long)num2); _voiceClip.GetData(val, _lastSample); IntPtr pointer = ((Il2CppObjectBase)val).Pointer; int size = IntPtr.Size; if (_loopedData) { _lastSample = 0; _loopedData = false; } else { _lastSample = num; } float[] array = new float[num2]; InteropUtilities.Copy(pointer, size, num2, array); bool isTalking = false; _amplitude = 0f; for (int i = 0; i < num2; i++) { float num3 = array[i] * 10f; SampleBuffer[i] = num3; _amplitude += System.Math.Abs(num3); if (!isTalking) { isTalking = System.Math.Abs(num3) >= 0.3f; } } if (num2 > 0) { _amplitude /= num2; } CheckTalkingTimeout(ref isTalking); _hasVoiceActivity = isTalking; if (!isTalking) { _amplitude = 0f; _encodedData = null; return; } SendToSources(SampleBuffer, num2); short[] array2 = new short[num2]; VoiceConverter.CopySamples(array, array2, num2); _encodedData = VoiceConverter.Encode(array2); } private static void SendToSources(float[] buffer, int sampleCount) { IEnumerable<VoiceSource> voicesByID = VoiceSourceManager.GetVoicesByID(PlayerIDManager.LocalSmallID); if (voicesByID.Any()) { float volumeMultiplier = VoiceVolume.GetVolumeMultiplier(); float num = volumeMultiplier * volumeMultiplier; float num2 = 0f; for (int i = 0; i < sampleCount; i++) { float num3 = buffer[i] * num; VoiceSourceManager.EnqueueSample(voicesByID, num3); num2 += System.Math.Abs(num3); } VoiceSourceManager.SetAmplitude(voicesByID, num2); } } private void CheckTalkingTimeout(ref bool isTalking) { if (isTalking) { _lastTalkTime = TimeUtilities.TimeSinceStartup; } else { isTalking = TimeUtilities.TimeSinceStartup - _lastTalkTime <= 1f; } } public void Enable() { } public void Disable() { _encodedData = null; _hasVoiceActivity = false; } } public class UnityVoiceSpeaker : VoiceSpeaker { public override float Amplitude { get; set; } public UnityVoiceSpeaker(PlayerID id) { _id = id; ContactsList.OnContactUpdated += OnContactUpdated; OnContactUpdated(ContactsList.GetContact(id)); } public override void Cleanup() { ContactsList.OnContactUpdated -= OnContactUpdated; } private void OnContactUpdated(Contact contact) { if (contact.id == _id.PlatformID) { base.Volume = contact.volume; } } public override void OnVoiceDataReceived(byte[] data) { short[] array = VoiceConverter.Decode(data); int num = array.Length; float[] array2 = new float[num]; VoiceConverter.CopySamples(array, array2, num); float num2 = VoiceVolume.GetVolumeMultiplier() * base.Volume; float num3 = num2 * num2; float num4 = 0f; IEnumerable<VoiceSource> voicesByID = VoiceSourceManager.GetVoicesByID(base.ID.SmallID); for (int i = 0; i < num; i++) { float num5 = array2[i] * num3 * 10f; VoiceSourceManager.EnqueueSample(voicesByID, num5); num4 += System.Math.Abs(num5); } if (num > 0) { num4 /= (float)num; } Amplitude = num4; VoiceSourceManager.SetAmplitude(voicesByID, num4); } } } namespace LabFusion.Utilities { public static class AssemblyUtilities { public static bool IsValid(this Assembly assembly) { if (assembly.FullName.Contains("System")) { return false; } return true; } public static bool IsValid(this Type type) { if (type.Name.Contains("Mono") && type.Name.Contains("Security")) { return false; } return true; } public static void LoadAllValid<T>(Assembly assembly, Action<Type> runOnValid) { if (!assembly.IsValid()) { return; } Type[] types = assembly.GetTypes(); foreach (Type type in types) { if (type.IsValid() && typeof(T).IsAssignableFrom(type) && !type.IsAbstract && !type.IsInterface) { try { runOnValid(type); } catch (Exception ex) { FusionLogger.Error(ex.Message); } } } } } public static class ConstrainerUtilities { private static Action _constrainerCreatedCallback; public const string ConstrainerAssetGUID = "bf9c97bf88c22dc4f981578e75d9aa12"; public static bool PlayerConstraintsEnabled => LobbyInfoManager.LobbyInfo.PlayerConstraining; public static bool HasConstrainer => (Object)(object)GlobalConstrainer != (Object)null; public static Constrainer GlobalConstrainer { get; private set; } public static void OnMainSceneInitialized() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown SpawnableCrate crate = CrateFilterer.GetCrate<SpawnableCrate>(((ScannableReference)BonelabSpawnableReferences.ConstrainerReference).Barcode); if (!((Object)(object)crate == (Object)null)) { if (!((Crate)crate).Pallet.IsInMarrowGame()) { ((Crate)crate).MainAsset = new MarrowAsset("bf9c97bf88c22dc4f981578e75d9aa12"); } Action<GameObject> action = OnConstrainerLoaded; ((CrateT<GameObject>)(object)crate).LoadAsset(Action<GameObject>.op_Implicit(action)); } } private static void OnConstrainerLoaded(GameObject go) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null) { _constrainerCreatedCallback = null; return; } GameObject obj = Object.Instantiate<GameObject>(go, new Vector3(1000f, 1000f, 1000f), QuaternionExtensions.identity); GlobalConstrainer = obj.GetComponent<Constrainer>(); obj.SetActive(false); _constrainerCreatedCallback?.InvokeSafe("executing Constrainer Created callback"); _constrainerCreatedCallback = null; } public static void HookConstrainerCreated(Action callback) { if (HasConstrainer) { callback?.Invoke(); } else { _constrainerCreatedCallback = (Action)Delegate.Combine(_constrainerCreatedCallback, callback); } } } public static class DelayUtilities { private class FrameDelayInfo { public Action Action; public int Counter; } private static readonly List<FrameDelayInfo> _delays = new List<FrameDelayInfo>(); public static void InvokeDelayed(Action action, int frames) { _delays.Add(new FrameDelayInfo { Action = action, Counter = frames }); } public static void InvokeNextFrame(Action action) { InvokeDelayed(action, 1); } internal static void OnProcessDelays() { for (int num = _delays.Count - 1; num >= 0; num--) { FrameDelayInfo frameDelayInfo = _delays[num]; if (frameDelayInfo.Counter <= 0) { try { frameDelayInfo.Action(); } catch (Exception ex) { FusionLogger.Error(ex.ToString()); } _delays.RemoveAt(num); } else { frameDelayInfo.Counter--; } } } } public static class DllTools { [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)] public static extern IntPtr LoadLibrary(string lpLibFileName); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FreeLibrary(IntPtr hModule); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern uint GetLastError(); } public readonly struct FrameBool { private readonly bool _value; private readonly int _frame; public bool Value { get { if (_value) { return Valid; } return false; } } public int Frame => _frame; public bool Valid => TimeUtilities.FrameCount == Frame; public FrameBool(bool value) { _value = value; _frame = TimeUtilities.FrameCount; } public static implicit operator bool(FrameBool value) { return value.Value; } public static implicit operator FrameBool(bool value) { return new FrameBool(value); } } public class FusionComponentCache<TSource, TComponent> where TSource : Object where TComponent : class { private readonly Dictionary<TSource, TComponent> _cache = new Dictionary<TSource, TComponent>((IEqualityComparer<TSource>?)new UnityComparer()); public ICollection<TComponent> Components => _cache.Values; public TComponent Get(TSource source) { if (_cache.TryGetValue(source, out var value)) { return value; } return null; } public bool TryGet(TSource source, out TComponent value) { return _cache.TryGetValue(source, out value); } public bool ContainsSource(TSource source) { return _cache.ContainsKey(source); } public void Add(TSource source, TComponent component) { if (_cache.ContainsKey(source)) { _cache[source] = component; } else { _cache.Add(source, component); } } public void Remove(TSource source) { _cache.Remove(source); } } public static class FusionDevTools { public static bool DevToolsDisabled { get { if (GamemodeManager.IsGamemodeStarted && GamemodeManager.ActiveGamemode.DisableDevTools) { return true; } return false; } } public static bool DespawnConstrainer(PlayerID id) { FusionPermissions.FetchPermissionLevel(id, out var level, out var _); if (!FusionPermissions.HasSufficientPermissions(level, LobbyInfoManager.LobbyInfo.Constrainer)) { return true; } return false; } public static bool DespawnDevTool(PlayerID id) { if (DevToolsDisabled) { return true; } FusionPermissions.FetchPermissionLevel(id, out var level, out var _); if (!FusionPermissions.HasSufficientPermissions(level, LobbyInfoManager.LobbyInfo.DevTools)) { return true; } return false; } public static bool PreventSpawnGun(PlayerID id) { if (GamemodeManager.IsGamemodeStarted && GamemodeManager.ActiveGamemode.DisableSpawnGun) { return true; } FusionPermissions.FetchPermissionLevel(id, out var level, out var _); if (!FusionPermissions.HasSufficientPermissions(level, LobbyInfoManager.LobbyInfo.DevTools)) { return true; } return false; } } internal static class FusionLogger { internal static void LogLine([CallerLineNumber] int lineNumber = 0) { Log($"FusionLogger.LogLine is only for debugging! Please remove from line {lineNumber}", ConsoleColor.Red); } internal static void Log(string txt, ConsoleColor txt_color = ConsoleColor.White) { ((MelonBase)FusionMod.Instance).LoggerInstance.Msg(txt_color, txt); } internal static void Log(object obj, ConsoleColor txt_color = ConsoleColor.White) { ((MelonBase)FusionMod.Instance).LoggerInstance.Msg(txt_color, obj); } internal static void Warn(string txt) { ((MelonBase)FusionMod.Instance).LoggerInstance.Warning(txt); } internal static void Warn(object obj) { ((MelonBase)FusionMod.Instance).LoggerInstance.Warning(obj); } internal static void Error(string txt) { ((MelonBase)FusionMod.Instance).LoggerInstance.Error(txt); } internal static void ErrorLine(string txt, [CallerLineNumber] int lineNumber = 0) { ((MelonBase)FusionMod.Instance).LoggerInstance.Error($"{txt} - Line: {lineNumber}"); } internal static void Error(object obj) { ((MelonBase)FusionMod.Instance).LoggerInstance.Error(obj); } internal static void LogException(string task, Exception e) { if (e.InnerException != null) { e = e.InnerException; } Error($"Failed {task} with reason: {e.Message}\nTrace:{e.StackTrace}"); } } public delegate bool UserOverride(PlayerID id); public static class FusionOverrides { private static UserOverride _onValidateNametag; public static event UserOverride OnValidateNametag { add { _onValidateNametag = (UserOverride)Delegate.Combine(_onValidateNametag, value); ForceUpdateOverrides(); } remove { _onValidateNametag = (UserOverride)Delegate.Remove(_onValidateNametag, value); ForceUpdateOverrides(); } } public static event Action OnOverridesChanged; public static bool ValidateNametag(PlayerID id) { if (_onValidateNametag == null) { return true; } Delegate[] invocationList = _onValidateNametag.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { if (!((UserOverride)invocationList[i])(id)) { return false; } } return true; } public static void ForceUpdateOverrides() { FusionOverrides.OnOverridesChanged.InvokeSafe("executing OnOverridesChanged"); } } public static class FusionPlayer { public static readonly List<Transform> SpawnPoints = new List<Transform>(); private static bool _brokeBounds = false; public static byte? LastAttacker { get; internal set; } internal static void OnMainSceneInitialized() { LastAttacker = null; if (_brokeBounds) { Physics.autoSimulation = true; _brokeBounds = false; } } internal static void OnUpdate() { if (!FusionSceneManager.IsLoading() && RigData.HasPlayer) { CheckFloatingPoint(); } } private static void CheckFloatingPoint() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!NetworkTransformManager.IsInBounds(RigData.Refs.RigManager.physicsRig.feet.transform.position)) { Physics.autoSimulation = false; _brokeBounds = true; if (NetworkInfo.HasServer && !NetworkInfo.IsHost) { NetworkHelper.Disconnect("Left Bounds"); } SceneStreamer.Reload(); Notifier.Send(new Notification { ShowPopup = true, Title = "Whoops! Sorry about that!", Type = NotificationType.WARNING, Message = "The scene was reloaded due to being sent far out of bounds.", PopupLength = 6f }); } } public static bool TryGetLastAttacker(out PlayerID id) { id = null; if (!LastAttacker.HasValue) { return false; } id = PlayerIDManager.GetPlayerID(LastAttacker.Value); return id != null; } public static bool IsLocalPlayer(this RigManager rigManager) { if (!RigData.HasPlayer) { return true; } return (Object)(object)rigManager == (Object)(object)RigData.Refs.RigManager; } public static void SetSpawnPoints(params Transform[] points) { SpawnPoints.Clear(); SpawnPoints.AddRange(points); } public static void ResetSpawnPoints() { SpawnPoints.Clear(); } public static bool TryGetSpawnPoint(out Transform point) { point = null; SpawnPoints.RemoveAll((Transform t) => (Object)(object)t == (Object)null); if (SpawnPoints.Count > 0) { point = SpawnPoints.GetRandom(); return true; } return false; } } public delegate bool UserAccessEvent(PlayerID playerId, out string reason); public delegate void ServerEvent(); public delegate void UpdateEvent(); public delegate void PlayerUpdate(PlayerID playerId); public delegate void PlayerAction(PlayerID playerId, PlayerActionType type, PlayerID otherPlayer = null); public static class MultiplayerHooking { public static event UserAccessEvent OnShouldAllowConnection; public static event ServerEvent OnStartedServer; public static event ServerEvent OnJoinedServer; public static event ServerEvent OnDisconnected; public static event PlayerUpdate OnPlayerJoined; public static event PlayerUpdate OnPlayerLeft; public static event PlayerAction OnPlayerAction; public static event UpdateEvent OnUpdate; public static event UpdateEvent OnFixedUpdate; public static event UpdateEvent OnLateUpdate; public static event UpdateEvent OnMainSceneInitialized; public static event UpdateEvent OnLoadingBegin; public static event UpdateEvent OnTargetLevelLoaded; internal static bool CheckShouldAllowConnection(PlayerID playerId, out string reason) { reason = ""; if (MultiplayerHooking.OnShouldAllowConnection == null) { return true; } Delegate[] invocationList = MultiplayerHooking.OnShouldAllowConnection.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { if (!((UserAccessEvent)invocationList[i])(playerId, out reason)) { return false; } } return true; } internal static void InvokeOnStartedServer() { MultiplayerHooking.OnStartedServer.InvokeSafe("executing OnStartedServer hook"); } internal static void InvokeOnJoinedServer() { MultiplayerHooking.OnJoinedServer.InvokeSafe("executing OnJoinedServer hook"); } internal static void InvokeOnDisconnected() { MultiplayerHooking.OnDisconnected.InvokeSafe("executing OnDisconnected hook"); } internal static void InvokeOnPlayerJoined(PlayerID id) { MultiplayerHooking.OnPlayerJoined.InvokeSafe(id, "executing OnPlayerJoined hook"); } internal static void InvokeOnPlayerLeft(PlayerID id) { MultiplayerHooking.OnPlayerLeft.InvokeSafe(id, "executing OnPlayerLeft hook"); } internal static void InvokeOnPlayerAction(PlayerID id, PlayerActionType type, PlayerID otherPlayer = null) { MultiplayerHooking.OnPlayerAction.InvokeSafe(id, type, otherPlayer, "executing OnPlayerAction hook"); } internal static void InvokeOnUpdate() { MultiplayerHooking.OnUpdate?.Invoke(); } internal static void InvokeOnFixedUpdate() { MultiplayerHooking.OnFixedUpdate?.Invoke(); } internal static void InvokeOnLateUpdate() { MultiplayerHooking.OnLateUpdate?.Invoke(); } internal static void InvokeOnMainSceneInitialized() { MultiplayerHooking.OnMainSceneInitialized.InvokeSafe("executing OnMainSceneInitialized hook"); } internal static void InvokeOnLoadingBegin() { MultiplayerHooking.OnLoadingBegin.InvokeSafe("executing OnLoadingBegin hook"); } internal static void InvokeTargetLevelLoaded() { MultiplayerHooking.OnTargetLevelLoaded.InvokeSafe("executing OnTargetLevelLoaded hook"); } } public static class GameObjectUtilities { private static readonly List<GameObject> _rootObjectBuffer = new List<GameObject>(); internal static List<GameObject> FindRootsWithName(string scene, string name) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) Scene sceneByName = SceneManager.GetSceneByName(scene); if (!((Scene)(ref sceneByName)).IsValid()) { return null; } _rootObjectBuffer.Capacity = ((Scene)(ref sceneByName)).rootCount; ((Scene)(ref sceneByName)).GetRootGameObjects(_rootObjectBuffer); _rootObjectBuffer.RemoveAll(Predicate<GameObject>.op_Implicit((Func<GameObject, bool>)((GameObject g) => ((Object)g).name != name))); return _rootObjectBuffer; } internal static int GetRootIndex(this GameObject go) { //IL_0013: 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) Scene scene = go.scene; return FindRootsWithName(((Scene)(ref scene)).name, ((Object)go).name).FindIndex(Predicate<GameObject>.op_Implicit((Func<GameObject, bool>)((GameObject g) => (Object)(object)g == (Object)(object)go))); } internal static GameObject GetRootByIndex(string scene, int index, string name) { List<GameObject> val = FindRootsWithName(scene, name); if (val == null || val.Count == 0) { return GameObject.Find("/" + name); } if (val.Count <= index) { return val[val.Count - 1]; } return val[index]; } public static string GetFullPath(this GameObject go) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) try { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(0, 4); Scene scene = go.scene; defaultInterpolatedStringHandler.AppendFormatted(((Scene)(ref scene)).name); defaultInterpolatedStringHandler.AppendFormatted('¬'); defaultInterpolatedStringHandler.AppendFormatted(((Component)go.transform.root).gameObject.GetRootIndex()); defaultInterpolatedStringHandler.AppendFormatted(go.transform.GetBasePath()); return defaultInterpolatedStringHandler.ToStringAndClear(); } catch { } return "INVALID_PATH"; } public static GameObject GetGameObject(string path) { string[] array = path.Split('¬'); string scene = array[0]; int index = int.Parse(array[1]); string name = array[2]; try { GameObject rootByIndex = GetRootByIndex(scene, index, name); if ((Object)(object)rootByIndex != (Object)null) { Transform val = rootByIndex.transform; for (int i = 3; i < array.Length; i++) { val = val.GetTransformByIndex(int.Parse(array[i++]), array[i]); } return ((Component)val).gameObject; } } catch (Exception) { } return null; } } public static class ImpactUtilities { public static void OnHitRigidbody(Rigidbody rb) { GameObject gameObject = ((Component)rb).gameObject; MarrowBody marrowBody = MarrowBody.Cache.Get(gameObject); if ((Object)(object)marrowBody == (Object)null) { return; } if (MarrowBodyExtender.Cache.TryGet(marrowBody, out var value)) { if (!value.IsOwnerLocked) { GripExtender extender = value.GetExtender<GripExtender>(); if (extender == null || !extender.CheckHeld()) { NetworkEntityManager.TakeOwnership(value); } } } else { DelayUtilities.InvokeDelayed(delegate { PropSender.SendPropCreation(marrowBody.Entity); }, 4); } } } internal static class PersistentAssetCreator { private const string _targetFont = "arlon-medium"; private static Action<HandPose> _onSoftGrabLoaded; internal static TMP_FontAsset Font { get; private set; } internal static HandPose SoftGrabPose { get; private set; } internal static void OnLateInitializeMelon() { CreateTextFont(); } internal static void OnMainSceneInitialized() { GetHandPose(); } private static void GetHandPose() { if (RigData.HasPlayer) { SoftGrabPose = RigData.Refs.RigManager.worldGripHandPose; } if ((Object)(object)SoftGrabPose != (Object)null) { _onSoftGrabLoaded?.Invoke(SoftGrabPose); } _onSoftGrabLoaded = null; } public static void HookOnSoftGrabLoaded(Action<HandPose> action) { if ((Object)(object)SoftGrabPose != (Object)null) { action?.Invoke(SoftGrabPose); } else { _onSoftGrabLoaded = (Action<HandPose>)Delegate.Combine(_onSoftGrabLoaded, action); } } private static void CreateTextFont() { Il2CppArrayBase<TMP_FontAsset> val = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); foreach (TMP_FontAsset item in val) { if (((Object)item).name.ToLower().Contains("arlon-medium")) { Font = item; break; } } if ((Object)(object)Font == (Object)null) { Font = val[0]; } } internal static void SetupImpactProperties(RigManager rig) { PhysicsRig physicsRig = rig.physicsRig; Il2CppArrayBase<Rigidbody> componentsInChildren = ((Component)physicsRig).GetComponentsInChildren<Rigidbody>(true); SurfaceData surfaceData = physicsRig._surfaceDataDefault; Avatar avatar = rig.avatar; if ((Object)(object)avatar != (Object)null && Object.op_Implicit((Object)(object)avatar.surfaceData)) { surfaceData = avatar.surfaceData; } List<ImpactProperties> list = new List<ImpactProperties>(); for (int i = 0; i < componentsInChildren.Length; i++) { Rigidbody obj = componentsInChildren[i]; GameObject gameObject = ((Component)obj).gameObject; if (!Object.op_Implicit((Object)(object)((Component)obj).GetComponent<ImpactProperties>()) && !((Object)(object)gameObject == (Object)(object)physicsRig.knee) && !((Object)(object)gameObject == (Object)(object)physicsRig.feet)) { ImpactProperties val = gameObject.AddComponent<ImpactProperties>(); val.surfaceData = surfaceData; val.decalType = (DecalType)(-1); list.Add(val); } } physicsRig._impactProperties = new Il2CppReferenceArray<ImpactProperties>(list.ToArray()); } } internal static class SafeEvents { internal static void InvokeSafe<T>(this T action, string task) where T : Delegate { if ((Delegate?)action == (Delegate?)null) { return; } Delegate[] invocationList = action.GetInvocationList(); foreach (Delegate @delegate in invocationList) { try { @delegate.DynamicInvoke(); } catch (Exception e) { FusionLogger.LogException(task, e); } } } internal static void InvokeSafe<T, T1>(this T action, T1 param, string task) where T : Delegate { if ((Delegate?)action == (Delegate?)null) { return; } Delegate[] invocationList = action.GetInvocationList(); foreach (Delegate @delegate in invocationList) { try { @delegate.DynamicInvoke(param); } catch (Exception e) { FusionLogger.LogException(task, e); } } } internal static void InvokeSafe<T, T1, T2>(this T action, T1 param1, T2 param2, string task) where T : Delegate { if ((Delegate?)action == (Delegate?)null) { return; } Delegate[] invocationList = action.GetInvocationList(); foreach (Delegate @delegate in invocationList) { try { @delegate.DynamicInvoke(param1, param2); } catch (Exception e) { FusionLogger.LogException(task, e); } } } internal static void InvokeSafe<T, T1, T2, T3>(this T action, T1 param1, T2 param2, T3 param3, string task) where T : Delegate { if ((Delegate?)action == (Delegate?)null) { return; } Delegate[] invocationList = action.GetInvocationList(); foreach (Delegate @delegate in invocationList) { try { @delegate.DynamicInvoke(param1, param2, param3); } catch (Exception e) { FusionLogger.LogException(task, e); } } } } internal static class TimeUtilities { private static float _deltaTime = 1f; private static float _fixedDeltaTime = 0.02f; private static float _timeSinceStartup = 0f; private static float _timeScale = 1f; private static int _frameCount = 0; public static float DeltaTime => _deltaTime; public static float FixedDeltaTime => _fixedDeltaTime; public static float TimeSinceStartup => _timeSinceStartup; public static float TimeScale => _timeScale; public static int FrameCount => _frameCount; internal static void OnEarlyUpdate() { _timeScale = Time.timeScale; _deltaTime = Time.deltaTime; _timeSinceStartup += _deltaTime; _frameCount++; } internal static void OnEarlyFixedUpdate() { _fixedDeltaTime = Time.fixedDeltaTime; } public static bool IsMatchingFrame(int interval) { return FrameCount % interval == 0; } public static bool IsMatchingFrame(int interval, int offset) { return (FrameCount + offset) % interval == 0; } } public static class InteropUtilities { public unsafe static void FloatArrayFastWrite(IntPtr pointer, int size, int index, float value) { *(float*)((byte*)IntPtr.Add(pointer, 4 * size).ToPointer() + (nint)index * (nint)4) = value; } public unsafe static float FloatArrayFastRead(IntPtr pointer, int size, int index) { return *(float*)((byte*)IntPtr.Add(pointer, 4 * size).ToPointer() + (nint)index * (nint)4); } public static void Copy(IntPtr pointer, int size, int length, float[] array) { for (int i = 0; i < length; i++) { array[i] = FloatArrayFastRead(pointer, size, i); } } } public static class MagazineUtilities { public static void ClaimMagazine(Magazine magazine, InventoryAmmoReceiver ammoReceiver) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) CartridgeData val = ammoReceiver.defaultLightCart; if ((Object)(object)ammoReceiver._selectedCartridgeData != (Object)null) { val = ammoReceiver._selectedCartridgeData; } if ((Object)(object)val != (Object)null && (Object)(object)val.projectile != (Object)null) { ProjectileEmitter.Register(val.projectile); } magazine.Initialize(val, AmmoInventory.Instance.GetCartridgeCount(val)); magazine.Claim(); LocalAudioPlayer.PlayAtPoint(Il2CppArrayBase<AudioClip>.op_Implicit((Il2CppArrayBase<AudioClip>)(object)ammoReceiver.grabClips), ((Component)ammoReceiver).transform.position, new AudioPlayerSettings { Mixer = LocalAudioPlayer.SoftInteraction, Volume = 0.2f }); } public static void GrabMagazine(Magazine magazine, NetworkPlayer player, Handedness handedness) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) player.HookOnReady(OnPlayerReady); void OnPlayerReady() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 RigManager rigManager = player.RigRefs.RigManager; InventoryAmmoReceiverExtender extender = player.NetworkEntity.GetExtender<InventoryAmmoReceiverExtender>(); if (extender != null) { ClaimMagazine(magazine, extender.Component); } Grip grip = magazine.grip; Hand found = (((int)handedness == 0) ? null : (((int)handedness == 1) ? rigManager.physicsRig.leftHand : rigManager.physicsRig.rightHand)); if (Object.op_Implicit((Object)(object)found)) { DelayUtilities.InvokeNextFrame(delegate { grip.MoveIntoHand(found); grip.TryAttach(found, isInstant: true); }); } } } } public static class MuteUIHelper { private static PageItem _mutePage; private static Poolee _indicatorPoolee; private static GameObject _indicatorGameObject; private static Renderer _indicatorRenderer; private static Camera _headsetCamera; public const string NotificationTag = "Mute"; public static void OnInitializeMelon() { FusionPref<bool> muted = ClientSettings.VoiceChat.Muted; muted.OnValueChanged = (Action<bool>)Delegate.Combine(muted.OnValueChanged, new Action<bool>(OnMutedChanged)); FusionPref<bool> mutedIndicator = ClientSettings.VoiceChat.MutedIndicator; mutedIndicator.OnValueChanged = (Action<bool>)Delegate.Combine(mutedIndicator.OnValueChanged, new Action<bool>(OnIndicatorChanged)); RenderPipelineManager.beginCameraRendering += Action<ScriptableRenderContext, Camera>.op_Implicit((Action<ScriptableRenderContext, Camera>)OnBeginCameraRendering); RenderPipelineManager.endCameraRendering += Action<ScriptableRenderContext, Camera>.op_Implicit((Action<ScriptableRenderContext, Camera>)OnEndCameraRendering); } public static void OnDeinitializeMelon() { FusionPref<bool> muted = ClientSettings.VoiceChat.Muted; muted.OnValueChanged = (Action<bool>)Delegate.Remove(muted.OnValueChanged, new Action<bool>(OnMutedChanged)); FusionPref<bool> mutedIndicator = ClientSettings.VoiceChat.MutedIndicator; mutedIndicator.OnValueChanged = (Action<bool>)Delegate.Remove(mutedIndicator.OnValueChanged, new Action<bool>(OnIndicatorChanged)); RenderPipelineManager.beginCameraRendering -= Action<ScriptableRenderContext, Camera>.op_Implicit((Action<ScriptableRenderContext, Camera>)OnBeginCameraRendering); RenderPipelineManager.endCameraRendering -= Action<ScriptableRenderContext, Camera>.op_Implicit((Action<ScriptableRenderContext, Camera>)OnEndCameraRendering); } private static void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera) { if (!((Object)(object)camera != (Object)(object)_headsetCamera) && !((Object)(object)_indicatorRenderer == (Object)null)) { _indicatorRenderer.enabled = true; } } private static void OnEndCameraRendering(ScriptableRenderContext context, Camera camera) { if (!((Object)(object)camera != (Object)(object)_headsetCamera) && !((Object)(object)_indicatorRenderer == (Object)null)) { _indicatorRenderer.enabled = false; } } private static void OnMutedChanged(bool value) { if (_mutePage != null) { _mutePage.name = (value ? "Quick Unmute" : "Quick Mute"); } UpdateMuteIcon(); } private static void OnIndicatorChanged(bool value) { UpdateMuteIcon(); } private static void UpdateMuteIcon() { if (!((Object)(object)_indicatorGameObject == (Object)null)) { _indicatorGameObject.SetActive(VoiceInfo.ShowMuteIndicator); } } public static void OnCreateMuteUI(RigManager manager) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) if (!VoiceInfo.CanTalk) { return; } PopUpMenuView popUpMenu = UIRig.Instance.popUpMenu; Page homePage = popUpMenu.radialPageView.m_HomePage; FusionPref<bool> mutedPref = ClientSettings.VoiceChat.Muted; _mutePage = new PageItem(mutedPref.Value ? "Quick Unmute" : "Quick Mute", (Directions)3, Action.op_Implicit((Action)delegate { mutedPref.Value = !mutedPref.Value; popUpMenu.Deactivate(); Notifier.Cancel("Mute"); Notifier.Send(new Notification { ShowPopup = true, SaveToMenu = false, Message = (mutedPref.Value ? "Muted" : "Unmuted"), Tag = "Mute" }); })); homePage.items.Add(_mutePage); OpenControllerRig val = ((Il2CppObjectBase)manager.ControllerRig).TryCast<OpenControllerRig>(); Transform headset = val.headset; Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(FusionSpawnableReferences.MuteIndicatorReference); LocalAssetSpawner.Register(spawnable); LocalAssetSpawner.Spawn(spawnable, Vector3.zero, Quaternion.identity, delegate(Poolee poolee) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) _indicatorPoolee = poolee; _indicatorGameObject = ((Component)poolee).gameObject; _indicatorGameObject.SetActive(false); ((Object)_indicatorGameObject).name = "Mute Icon [FUSION]"; _indicatorRenderer = _indicatorGameObject.GetComponentInChildren<Renderer>(); _indicatorRenderer.enabled = false; if (!((Object)(object)headset == (Object)null)) { _headsetCamera = ((Component)headset).GetComponent<Camera>(); Transform transform = _indicatorGameObject.transform; transform.parent = headset; transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); UpdateMuteIcon(); } }); } public static void OnDestroyMuteUI() { if (_mutePage != null) { PopUpMenuView popUpMenu = UIRig.Instance.popUpMenu; Page homePage = popUpMenu.radialPageView.m_HomePage; homePage.items.RemoveAll(Predicate<PageItem>.op_Implicit((Func<PageItem, bool>)((PageItem i) => i.name == _mutePage.name))); popUpMenu.radialPageView.Render(homePage); _mutePage = null; } if ((Object)(object)_indicatorPoolee != (Object)null) { _indicatorPoolee.Despawn(); _indicatorPoolee = null; _indicatorGameObject = null; _indicatorRenderer = null; } } } public static class PlatformHelper { private static readonly bool _isAndroidCached = (int)MelonUtils.CurrentPlatform == 3; public const string AndroidName = "QUEST"; public const string WindowsName = "PC"; public static bool IsAndroid => _isAndroidCached; public static string GetPlatformName() { if (IsAndroid) { return "QUEST"; } return "PC"; } } public static class PlayerAdditionsHelper { public static void OnInitializeMelon() { MultiplayerHooking.OnJoinedServer += delegate { OnEnterServer(RigData.Refs.RigManager); }; MultiplayerHooking.OnStartedServer += delegate { OnEnterServer(RigData.Refs.RigManager); }; MultiplayerHooking.OnDisconnected += delegate { OnExitServer(RigData.Refs.RigManager); }; LocalPlayer.OnLocalRigCreated = (Action<RigManager>)Delegate.Combine(LocalPlayer.OnLocalRigCreated, (Action<RigManager>)delegate(RigManager rig) { if (NetworkInfo.HasServer) { OnEnterServer(rig); } }); MuteUIHelper.OnInitializeMelon(); } public static void OnDeinitializeMelon() { MuteUIHelper.OnDeinitializeMelon(); } public static void OnEnterServer(RigManager manager) { if (!((Object)(object)manager == (Object)null)) { MuteUIHelper.OnCreateMuteUI(manager); PersistentAssetCreator.SetupImpactProperties(manager); manager.health._testVisualDamage = true; Player_Health obj = ((Il2CppObjectBase)manager.health).TryCast<Player_Health>(); obj.reloadLevelOnDeath = false; obj.slowMoOnDeath = false; PhysicsRig physicsRig = manager.physicsRig; ((Component)((Rig)physicsRig).m_handLf).gameObject.AddComponent<CollisionSyncer>(); ((Component)((Rig)physicsRig).m_elbowLf).gameObject.AddComponent<CollisionSyncer>(); ((Component)((Rig)physicsRig).m_shoulderLf).gameObject.AddComponent<CollisionSyncer>(); ((Component)((Rig)physicsRig).m_handRt).gameObject.AddComponent<CollisionSyncer>(); ((Component)((Rig)physicsRig).m_elbowRt).gameObject.AddComponent<CollisionSyncer>(); ((Component)((Rig)physicsRig).m_shoulderRt).gameObject.AddComponent<CollisionSyncer>(); physicsRig.feet.gameObject.AddComponent<CollisionSyncer>(); ((Component)((Rig)physicsRig).m_head).gameObject.AddComponent<CollisionSyncer>(); } } public static void OnExitServer(RigManager manager) { if ((Object)(object)manager == (Object)null) { return; } MuteUIHelper.OnDestroyMuteUI(); manager.physicsRig._impactProperties = new Il2CppReferenceArray<ImpactProperties>(0L); foreach (ImpactProperties componentsInChild in ((Component)manager).GetComponentsInChildren<ImpactProperties>(true)) { Object.Destroy((Object)(object)componentsInChild); } foreach (CollisionSyncer componentsInChild2 in ((Component)manager).GetComponentsInChildren<CollisionSyncer>(true)) { Object.Destroy((Object)(object)componentsInChild2); } manager.health._testVisualDamage = false; ((Il2CppObjectBase)manager.health).TryCast<Player_Health>().slowMoOnDeath = true; } } public static class PooleeUtilities { public static void DespawnAll() { if (!NetworkInfo.IsHost) { return; } NetworkEntity[] array = NetworkEntityManager.IDManager.RegisteredEntities.EntityIDLookup.Keys.ToArray(); foreach (NetworkEntity networkEntity in array) { if (networkEntity.GetExtender<NetworkProp>() != null) { PooleeExtender extender = networkEntity.GetExtender<PooleeExtender>(); if (extender != null) { extender.Component.Despawn(); } } } } public static void SendDespawn(ushort entityId, bool despawnEffect) { if (NetworkInfo.IsHost) { MessageRelay.RelayNative(new DespawnResponseData { Despawner = new PlayerReference(PlayerIDManager.LocalSmallID), Entity = new NetworkEntityReference(entityId), DespawnEffect = despawnEffect }, NativeMessageTag.DespawnResponse, CommonMessageRoutes.ReliableToOtherClients); } else { RequestDespawn(entityId, despawnEffect); } } public static void RequestDespawn(ushort entityId, bool despawnEffect) { MessageRelay.RelayNative(new DespawnRequestData { Entity = new NetworkEntityReference(entityId), DespawnEffect = despawnEffect }, NativeMessageTag.DespawnRequest, CommonMessageRoutes.ReliableToServer); } public static void RequestSpawn(string barcode, SerializedTransform serializedTransform, uint trackerId, bool spawnEffect) { MessageRelay.RelayNative(SpawnRequestData.Create(barcode, serializedTransform, trackerId, spawnEffect), NativeMessageTag.SpawnRequest, CommonMessageRoutes.ReliableToServer); } public static void SendSpawn(byte owner, string barcode, ushort syncId, SerializedTransform serializedTransform, uint trackerId = 0u, bool spawnEffect = false) { MessageRelay.RelayNative(SpawnResponseData.Create(owner, barcode, syncId, serializedTransform, trackerId, spawnEffect), NativeMessageTag.SpawnResponse, CommonMessageRoutes.ReliableToClients); } } public static class TriggerUtilities { public static bool IsMatchingRig(TriggerRefProxy proxy, RigManager rig) { if (!NetworkInfo.HasServer || !RigData.HasPlayer) { return true; } RigManager val; if (Object.op_Implicit((Object)(object)proxy.root) && Object.op_Implicit((Object)(object)(val = RigManager.Cache.Get(proxy.root)))) { return (Object)(object)val == (Object)(object)rig; } return false; } } public static class LaserCursorUtilities { public static void CreateLaserCursor(Action<LaserCursor> onCursorReady = null) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(FusionSpawnableReferences.LaserCursorReference); LocalAssetSpawner.Register(spawnable); LocalAssetSpawner.Spawn(spawnable, Vector3.zero, Quaternion.identity, delegate(Poolee poolee) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown GameObject gameObject = ((Component)poolee).gameObject; Transform transform = gameObject.transform; gameObject.SetActive(false); LaserCursor cursor = gameObject.AddComponent<LaserCursor>(); PageElementView val = transform.Find("Arrow").SetupPageElementView(); PageElementView val2 = transform.Find("ray_start").SetupPageElementView(); PageElementView val3 = transform.Find("ray_mid").SetupPageElementView(); PageElementView val4 = transform.Find("ray_mid2").SetupPageElementView(); PageElementView val5 = transform.Find("ray_bez").SetupPageElementView(); PageElementView val6 = transform.Find("ray_end").SetupPageElementView(); PageElementView rayPulse = transform.Find("ray_pulse").SetupPageElementView(); PageElementView val7 = transform.Find("SFX").SetupPageElementView(); AnimationCurve blipCurve = (val4.blipCurve = (val3.blipCurve = (val2.blipCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[4] { new Keyframe(0f, 1f), new Keyframe(0.1271991f, 1.953225f), new Keyframe(0.724905f, 0.9818711f), new Keyframe(1f, 1f) })))); val6.blipCurve = blipCurve; DrawBezierCurve val11 = ((Component)val).gameObject.AddComponent<DrawBezierCurve>(); val11.Point1 = ((Component)val6).gameObject; val11.Point2 = ((Component)val5).gameObject; val11.Point3 = ((Component)val3).gameObject; val11.Point4 = ((Component)val2).gameObject; val11.lineSteps = 12; val11.linePercentageFill = 0.73f; PrismaticSFX prismaticSFX = ((Component)val7).gameObject.AddComponent<PrismaticSFX>(); prismaticSFX.velocityTran = ((Component)val7).transform; prismaticSFX.sourceTran = ((Component)val7).transform; prismaticSFX.minSpeed = 0.2f; prismaticSFX.maxSpeed = 4f; prismaticSFX.sourceMinDistance = 1f; prismaticSFX.pitchMod = 1f; prismaticSFX.loopClips = true; AudioLoader.LoadMonoDisc(FusionMonoDiscReferences.LaserPrismaticSFXReference, delegate(AudioClip clip) { prismaticSFX.modulatedClips = Il2CppReferenceArray<AudioClip>.op_Implicit((AudioClip[])(object)new AudioClip[1] { clip }); }); prismaticSFX.SpatialBlend = 0.98f; cursor.cursorStart = val2; cursor.cursorEnd = val6; cursor.cursorMid = val3; cursor.cursorMid2 = val4; cursor.cursorBez = val5; cursor.rayPulse = rayPulse; cursor.lineEnd = val; cursor.cursorLine = ((Component)val).GetComponent<LineRenderer>(); cursor.bezCurve = val11; cursor.pulseLength = 0.2f; cursor.pulseAceleration = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); AudioLoader.LoadMonoDisc(FusionMonoDiscReferences.LaserPulseReference, delegate(AudioClip clip) { cursor.pulseSound = Il2CppReferenceArray<AudioClip>.op_Implicit((AudioClip[])(object)new AudioClip[1] { clip }); }); AudioLoader.LoadMonoDisc(FusionMonoDiscReferences.LaserRaySpawnReference, delegate(AudioClip clip) { cursor.raySpawn = Il2CppReferenceArray<AudioClip>.op_Implicit((AudioClip[])(object)new AudioClip[1] { clip }); }); AudioLoader.LoadMonoDisc(FusionMonoDiscReferences.LaserRayDespawnReference, delegate(AudioClip clip) { cursor.rayDespawn = Il2CppReferenceArray<AudioClip>.op_Implicit((AudioClip[])(object)new AudioClip[1] { clip }); }); cursor.prismaticSFX = prismaticSFX; cursor.spatialBlend = 1f; cursor._sourceVolume = 0.3f; cursor._sourceRadius = 1f; cursor.cursorHidden = true; cursor.canShowCursor = true; cursor.maxMillimeters = 16f; onCursorReady?.Invoke(cursor); }); } private static PageElementView SetupPageElementView(this Transform transform) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) HighlightUI val = ((Component)transform).gameObject.AddComponent<HighlightUI>(); val.color1 = new Color(1f, 1f, 1f, 0.1294118f); val.color2 = Color.white; PageElementView val2 = ((Component)transform).gameObject.AddComponent<PageElementView>(); val2.highlightColor1 = new Color(1f, 1f, 1f, 0f); val2.highlightColor2 = Color.white; val2.color1 = new Color(1f, 1f, 1f, 0f); val2.color2 = Color.white; val2.blipCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f); val2.elements = Il2CppReferenceArray<HighlightUI>.op_Implicit((HighlightUI[])(object)new HighlightUI[1] { val }); return val2; } } public static class UIMachineUtilities { public static void CreateLaserCursor(Transform canvas, Transform uiPlane, Vector3 bounds) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) LaserCursorUtilities.CreateLaserCursor(delegate(LaserCursor cursor) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown ((Component)cursor).transform.parent = canvas.parent; ((Component)cursor).transform.SetLocalPositionAndRotation(Vector3Extensions.zero, QuaternionExtensions.identity); CursorRegion val = new CursorRegion { bounds = new Bounds(Vector3Extensions.zero, Vector3.Scale(bounds, canvas.lossyScale)), center = uiPlane }; cursor.regions = Il2CppReferenceArray<CursorRegion>.op_Implicit((CursorRegion[])(object)new CursorRegion[1] { val }); FusionSceneManager.HookOnLevelLoad(delegate { if (!((Object)(object)cursor == (Object)null)) { ((Component)cursor).gameObject.SetActive(true); } }); }); } public static void CreateUITrigger(GameObject canvas, GameObject trigger) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown trigger.SetActive(false); trigger.layer = 29; Zone zone = trigger.AddComponent<Zone>(); ZoneEvents obj = trigger.AddComponent<ZoneEvents>(); ((ZoneItem)obj)._zone = zone; obj.onZoneEnter = new ZoneEventCallback(); obj.onZoneEnterOneShot = new ZoneEventCallback(); obj.onZoneExit = new ZoneEventCallback(); TagQuery val = new TagQuery { BoneTag = MarrowBoneTagReferences.PlayerReference }; ((ZoneItem)obj).activatorTags.Tags.Add(val); ((UltEvent<MarrowEntity>)(object)obj.onZoneEnter).DynamicCalls += Action<MarrowEntity>.op_Implicit((Action<MarrowEntity>)delegate { //IL_0021: Unknown result type (might be due to invalid IL or missing references) canvas.SetActive(true); LocalAudioPlayer.PlayAtPoint(new AudioReference(FusionMonoDiscReferences.UITurnOnReference), canvas.transform.position, LocalAudioPlayer.SFXSettings); }); ((UltEvent<MarrowEntity>)(object)obj.onZoneExit).DynamicCalls += Action<MarrowEntity>.op_Implicit((Action<MarrowEntity>)delegate { //IL_0021: Unknown result type (might be due to invalid IL or missing references) canvas.SetActive(false); LocalAudioPlayer.PlayAtPoint(new AudioReference(FusionMonoDiscReferences.UITurnOffReference), canvas.transform.position, LocalAudioPlayer.SFXSettings); }); trigger.SetActive(true); } public static void OverrideFonts(Transform root) { foreach (TMP_Text componentsInChild in ((Component)root).GetComponentsInChildren<TMP_Text>(true)) { componentsInChild.font = PersistentAssetCreator.Font; } } public static void AddButtonTriggers(Transform root) { foreach (Button componentsInChild in ((Component)root).GetComponentsInChildren<Button>(true)) { Collider componentInChildren = ((Component)componentsInChild).GetComponentInChildren<Collider>(true); if ((Object)(object)componentInChildren != (Object)null) { ((Component)componentInChildren).gameObject.AddComponent<FusionUITrigger>().button = componentsInChild; } } } public static void AddClickEvent(this Button button, Action action) { ((UnityEvent)button.onClick).AddListener(UnityAction.op_Implicit(action)); } } } namespace LabFusion.UI { [RegisterTypeInIl2Cpp] public sealed class CupBoard : FusionUIMachine { private const float _maxMusicVolume = 0.3f; private CupBoardPanelView _panelView; private AudioSource[] _musicLayers; private int _layerCount; private GameObject _completionistGo; public CupBoardPanelView PanelView => _panelView; public CupBoard(IntPtr intPtr) : base(intPtr) { } protected override void OnAwake() { base.OnAwake(); _musicLayers = Il2CppArrayBase<AudioSource>.op_Implicit(((Component)((Component)this).transform.Find("SFX/Music")).GetComponentsInChildren<AudioSource>()); _layerCount = _musicLayers.Length; _completionistGo = ((Component)((Component)this).transform.Find("Art/Offset/Completionist")).gameObject; LabFusion.SDK.Achievements.Achievement.OnAchievementCompleted += OnAchievementCompleted; LoadProgress(); } private void OnDestroy() { LabFusion.SDK.Achievements.Achievement.OnAchievementCompleted -= OnAchievementCompleted; } [HideFromIl2Cpp] private void OnAchievementCompleted(LabFusion.SDK.Achievements.Achievement achievement) { LoadProgress(); } private void LoadProgress() { float achievementProgress = AchievementManager.GetAchievementProgress(); LoadEffects(achievementProgress); LoadMusic(achievementProgress); AchievementManager.CheckCompletionistUnlocks(); } private void LoadEffects(float progress) { bool active = progress >= 1f; _completionistGo.SetActive(active); } private void LoadMusic(float progress) { _musicLayers[0].volume = 0.3f; int num = _layerCount - 1; float num2 = progress * (float)num; for (int i = 0; i < num; i++) { float t = num2 - (float)i; _musicLayers[i + 1].volume = ManagedMathf.Lerp(0f, 0.3f, t); } } protected override void AddPanelView(GameObject panel) { _panelView = panel.AddComponent<CupBoardPanelView>(); } protected override Transform GetGripRoot() { return ((Component)this).transform.Find("Colliders"); } } public static class CupBoardHelper { public static void CompleteAchievementBoard(GameObject gameObject) { gameObject.AddComponent<CupBoard>(); } public static void SpawnAchievementBoard(Vector3 position, Quaternion rotation) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(FusionSpawnableReferences.AchievementBoardReference); LocalAssetSpawner.Register(spawnable); LocalAssetSpawner.Spawn(spawnable, position, rotation); } } [RegisterTypeInIl2Cpp] public sealed class CupBoardPanelView : FusionPanelView { private Transform _achievementButtonsRoot; private Transform _arrowButtonsRoot; private Slider _progressSlider; private TMP_Text _progressText; private Transform[] _achievementPanels; private int _achievementButtonCount; private int _currentPageIndex; private int _pageCount; private Texture _defaultPreview; private TMP_Text _pageCountText; protected override Vector3 Bounds => new Vector3(2.14f, 1.4f, 0.1f); public int PageCount => _pageCount; [HideFromIl2Cpp] public IReadOnlyList<LabFusion.SDK.Achievements.Achievement> PageItems => AchievementManager.GetSortedAchievements(); public CupBoardPanelView(IntPtr intPtr) : base(intPtr) { } protected override void OnAwake() { base.OnAwake(); SetupArrows(); LabFusion.SDK.Achievements.Achievement.OnAchievementUpdated += OnAchievementUpdated; MenuResources.HookResourcesReady(LoadPage); } private void OnDestroy() { LabFusion.SDK.Achievements.Achievement.OnAchievementUpdated -= OnAchievementUpdated; } [HideFromIl2Cpp] private void OnAchievementUpdated(LabFusion.SDK.Achievements.Achievement achievement) { LoadPage(); } protected override void OnSetupReferences() { _achievementButtonsRoot = _canvas.Find("achievement_Buttons"); _arrowButtonsRoot = _canvas.Find("arrow_Buttons"); _progressSlider = ((Component)_canvas.Find("bar_Progress")).GetComponent<Slider>(); _progressText = ((Component)((Component)_progressSlider).transform.Find("text")).GetComponent<TMP_Text>(); _pageCountText = ((Component)_arrowButtonsRoot.Find("button_pageCount")).GetComponentInChildren<TMP_Text>(); _achievementButtonCount = _achievementButtonsRoot.childCount; _achievementPanels = (Transform[])(object)new Transform[_achievementButtonCount]; for (int i = 0; i < _achievementButtonCount; i++) { _achievementPanels[i] = _achievementButtonsRoot.GetChild(i); if (i == 0) { _defaultPreview = ((Component)_achievementPanels[i]).GetComponentInChildren<RawImage>().texture; } } } private void SetupArrows() { ((Component)_arrowButtonsRoot.Find("button_lastPage")).GetComponent<Button>().AddClickEvent(delegate { LastPage(); }); ((Component)_arrowButtonsRoot.Find("button_nextPage")).GetComponent<Button>().AddClickEvent(delegate { NextPage(); }); } public void NextPage() { _currentPageIndex++; if (_currentPageIndex >= PageCount) { _currentPageIndex = PageCount - 1; } LoadPage(); } public void LastPage() { _currentPageIndex--; if (_currentPageIndex < 0) { _currentPageIndex = 0; } LoadPage(); } private void LoadPage() { if (PageItems.Count <= 0) { _pageCount = 0; } else { _pageCount = (int)System.Math.Ceiling((double)PageItems.Count / (double)_achievementButtonCount); } _currentPageIndex = ManagedMathf.Clamp(_currentPageIndex, 0, PageCount); _pageCountText.text = $"Page {_currentPageIndex + 1} out of {System.Math.Max(1, PageCount)}"; for (int i = 0; i < _achievementButtonCount; i++) { Transform val = _achievementPanels[i]; int achievementIndex = GetAchievementIndex(i); if (PageItems.Count <= achievementIndex) { ((Component)val).gameObject.SetActive(false); continue; } ((Component)val).gameObject.SetActive(true); LoadAchievement(val, PageItems[achievementIndex]); } LoadProgress(); } private void LoadProgress() { float achievementProgress = AchievementManager.GetAchievementProgress(); _progressSlider.Set(achievementProgress, false); _progressText.text = $"{achievementProgress * 100f}%"; } [HideFromIl2Cpp] private void LoadAchievement(Transform transform, LabFusion.SDK.Achievements.Achievement achievement) { TMP_Text component = ((Component)transform.Find("title")).GetComponent<TMP_Text>(); TMP_Text component2 = ((Component)transform.Find("description")).GetComponent<TMP_Text>(); TMP_Text component3 = ((Component)transform.Find("progress")).GetComponent<TMP_Text>(); RawImage component4 = ((Component)transform.Find("icon")).GetComponent<RawImage>(); GameObject gameObject = ((Component)transform.Find("completed")).gameObject; GameObject gameObject2 = ((Component)transform.Find("incompleted")).gameObject; TMP_Text component5 = ((Component)component.transform.Find("button_bitCount").Find("text")).GetComponent<TMP_Text>(); component.text = achievement.Title; component2.text = achievement.Description; component5.text = achievement.BitReward.ToString(); component3.text = achievement.Progress; if ((Object)(object)achievement.Logo != (Object)null) { component4.texture = achievement.Logo; } else { component4.texture = _defaultPreview; } gameObject.SetActive(achievement.IsComplete); gameObject2.SetActive(!achievement.IsComplete); } private int GetAchievementIndex(int index) { return index + _currentPageIndex * _achievementButtonCount; } } public class FusionPanelView : MonoBehaviour { protected Transform _canvas; protected Transform _uiPlane; protected virtual Vector3 Bounds => new Vector3(1f, 1f, 0.1f); public FusionPanelView(IntPtr intPtr) : base(intPtr) { } private void Awake() { UIMachineUtilities.OverrideFonts(((Component)this).transform); UIMachineUtilities.AddButtonTriggers(((Component)this).transform); SetupReferences(); OnAwake(); ((Component)_canvas).gameObject.SetActive(false); } private void SetupReferences() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) _canvas = ((Component)this).transform.Find("CANVAS"); _uiPlane = _canvas.Find("UIPLANE"); UIMachineUtilities.CreateLaserCursor(_canvas, _uiPlane, Bounds); OnSetupReferences(); } protected virtual void OnAwake() { } protected virtual void OnSetupReferences() { } } public class FusionUIMachine : MonoBehaviour { public FusionUIMachine(IntPtr intPtr) : base(intPtr) { } private void Awake() { PersistentAssetCreator.HookOnSoftGrabLoaded(delegate(HandPose p) { foreach (Collider componentsInChild in ((Component)GetGripRoot()).GetComponentsInChildren<Collider>()) { if (!Object.op_Implicit((Object)(object)Grip.Cache.Get(((Component)componentsInChild).gameObject))) { GenericGrip obj = ((Component)componentsInChild).gameObject.AddComponent<GenericGrip>(); ((Grip)obj).isThrowable = true; ((Grip)obj).ignoreGripTargetOnAttach = false; ((Grip)obj).additionalGripColliders = Il2CppReferenceArray<Collider>.op_Implicit((Collider[])(object)new Collider[0]); ((Grip)obj).handleAmplifyCurve = AnimationCurve.Linear(0f, 1f, 0f, 1f); ((Grip)obj).gripOptions = (InteractionOptions)1; ((Grip)obj).priority = 1f; ((Grip)obj).handPose = p; ((Grip)obj).minBreakForce = float.PositiveInfinity; ((Grip)obj).maxBreakForce = float.PositiveInfinity; ((Grip)obj).defaultGripDistance = float.PositiveInfinity; ((Grip)obj).radius = 0.24f; } } foreach (Rigidbody componentsInChild2 in ((Component)((Component)this).transform).GetComponentsInChildren<Rigidbody>()) { ((Component)componentsInChild2).gameObject.AddComponent<InteractableHost>(); } }); Transform val = ((Component)this).transform.Find("PANELVIEW"); AddPanelView(((Component)val).gameObject); UIMachineUtilities.CreateUITrigger(((Component)val.Find("CANVAS")).gameObject, ((Component)((Component)this).transform.Find("uiTrigger")).gameObject); AudioSource[] array = Il2CppArrayBase<AudioSource>.op_Implicit(((Component)this).gameObject.GetComponentsInChildren<AudioSource>(true)); for (int i = 0; i < array.Length; i++) { array[i].outputAudioMixerGroup = Audio3dManager.diegeticMusic; } OnAwake(); } protected virtual void OnAwake() { } protected virtual void AddPanelView(GameObject panel) { } protected virtual Transform GetGripRoot() { return null; } } [RegisterTypeInIl2Cpp] public sealed class FusionUITrigger : MonoBehaviour { public Button button; public FusionUITrigger(IntPtr intPtr) : base(intPtr) { } private void Awake() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown EventTrigger obj = ((Component)this).gameObject.AddComponent<EventTrigger>(); Entry val = new Entry { eventID = (EventTriggerType)4 }; ((UnityEvent<BaseEventData>)(object)val.callback).AddListener(UnityAction<BaseEventData>.op_Implicit((Action<BaseEventData>)delegate { //IL_0010: Unknown result type (might be due to invalid IL or missing references) LocalAudioPlayer.PlayAtPoint(new AudioReference(FusionMonoDiscReferences.UIConfirmReference), ((Component)this).transform.position, LocalAudioPlayer.SFXSettings); ButtonClickedEvent onClick = button.onClick; if (onClick != null) { ((UnityEvent)onClick).Invoke(); } })); Entry val2 = new Entry { eventID = (EventTriggerType)0 }; ((UnityEvent<BaseEventData>)(object)val2.callback).AddListener(UnityAction<BaseEventData>.op_Implicit((Action<BaseEventData>)delegate { //IL_0010: Unknown result type (might be due to invalid IL or missing references) LocalAudioPlayer.PlayAtPoint(new AudioReference(FusionMonoDiscReferences.UISelectReference), ((Component)this).transform.position, LocalAudioPlayer.SFXSettings); })); obj.delegates.Add(val); obj.delegates.Add(val2); } } [RegisterTypeInIl2Cpp] public sealed class InfoBox : FusionUIMachine { private InfoBoxPanelView _panelView; public InfoBoxPanelView PanelView => _panelView; public InfoBox(IntPtr intPtr) : base(intPtr) { } protected override void AddPanelView(GameObject panel) { _panelView = panel.AddComponent<InfoBoxPanelView>(); } protected override Transform GetGripRoot() { return ((Component)this).transform.Find("Colliders"); } } public static class InfoBoxHelper { public static void CompleteInfoBoard(GameObject gameObject) { gameObject.AddComponent<InfoBox>(); } public static void SpawnInfoBoard(Vector3 position, Quaternion rotation) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(FusionSpawnableReferences.InfoBoardReference); LocalAssetSpawner.Register(spawnable); LocalAssetSpawner.Spawn(spawnable, position, rotation); } } [RegisterTypeInIl2Cpp] public sealed class InfoBoxPanelView : FusionPanelView { private TMP_Text _versionText; private TMP_Text _changelogText; private TMP_Text _credits01Text; private TMP_Text _credits02Text; private TMP_Text _credits03Text; private Transform _groupPatchNotes; private Transform _groupCredits; private Transform _groupMystery; private Button _patchNotesButton; private Button _creditsButton; private Button _mysteryButton; protected override Vector3 Bounds => new Vector3(0.64f, 0.64f, 0.1f); public InfoBoxPanelView(IntPtr intPtr) : base(intPtr) { } protected override void OnAwake() { SetupButtons(); LoadPage(((Component)_groupPatchNotes).gameObject); } protected override void OnSetupReferences() { _versionText = ((Component)_canvas.Find("text_versionNumber")).GetComponent<TMP_Text>(); _versionText.text = $"v{FusionMod.Version}"; _groupPatchNotes = _canvas.Find("group_patchNotes"); _groupCredits = _canvas.Find("group_credits"); _groupMystery = _canvas.Find("group_mystery"); _changelogText = ((Component)_groupPatchNotes.Find("button_changelogContents")).GetComponentInChildren<TMP_Text>(); _changelogText.text = FusionMod.Changelog; _credits01Text = ((Component)_groupCredits.Find("text_credits01")).GetComponentInChildren<TMP_Text>(); _credits02Text = ((Component)_groupCredits.Find("text_credits02")).GetComponentInChildren<TMP_Text>(); _credits03Text = ((Component)_groupCredits.Find("text_credits03")).GetComponentInChildren<TMP_Text>(); if (FusionMod.Credits != null) { _credits01Text.text = FusionMod.Credits[0]; _credits02Text.text = FusionMod.Credits[1]; _credits03Text.text = FusionMod.Credits[2]; } _patchNotesButton = ((Component)_canvas.Find("button_patchNotes")).GetComponent<Button>(); _creditsButton = ((Component)_canvas.Find("button_credits")).GetComponent<Button>(); _mysteryButton = ((Component)_canvas.Find("button_mystery")).GetComponent<Button>(); } private void SetupButtons() { _patchNotesButton.AddClickEvent(delegate { LoadPage(((Component)_groupPatchNotes).gameObject); }); _creditsButton.AddClickEvent(delegate { LoadPage(((Component)_groupCredits).gameObject); }); _mysteryButton.AddClickEvent(delegate { if (AchievementManager.TryGetAchievement<HelloThere>(out var achievement)) { achievement.IncrementTask(); } LoadPage(((Component)_groupMystery).gameObject); }); } private void LoadPage(GameObject page) { ((Component)_groupPatchNotes).gameObject.SetActive(false); ((Component)_groupCredits).gameObject.SetActive(false); ((Component)_groupMystery).gameObject.SetActive(false); page.SetActive(true); } } public interface IPopupLayoutElement { int Priority { get; } Transform Transform { get; } bool Visible { get; set; } void Spawn(Transform parent); void Despawn(); } } namespace LabFusion.UI.Popups { public static class AchievementPopup { public const float DefaultDuration = 5f; public static readonly Vector3 LocalPosition = new Vector3(0f, -0.06f, 0.9f); private static readonly Queue<LabFusion.SDK.Achievements.Achievement> _queuedAchievements = new Queue<LabFusion.SDK.Achievements.Achievement>(); private static float _timeOfPopup = 0f; public static void Send(LabFusion.SDK.Achievements.Achievement achievement) { QueueAchievement(achievement); } private static void QueueAchievement(LabFusion.SDK.Achievements.Achievement achievement) { _queuedAchievements.Enqueue(achievement); } private static void DequeueAchievement() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) _timeOfPopup = TimeUtilities.TimeSinceStartup; LabFusion.SDK.Achievements.Achievement achievement = _queuedAchievements.Dequeue(); Transform camera = ((Rig)RigData.Refs.ControllerRig).m_head; Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(FusionSpawnableReferences.AchievementPopupReference); LocalAssetSpawner.Register(spawnable); LocalAssetSpawner.Spawn(spawnable, Vector3.zero, Quaternion.identity, delegate(Poolee poolee) { //IL_001e: 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) Transform transform = ((Component)poolee).transform; transform.parent = camera; UIMachineUtilities.OverrideFonts(((Component)transform).transform); transform.localPosition = LocalPosition; transform.localRotation = Quaternion.identity; Transform val = transform.Find("Offset/Canvas"); if ((Object)(object)achievement.Logo != (Object)null) { ((Component)val.Find("icon")).GetComponent<RawImage>().texture = achievement.Logo; } ((Component)val.Find("title")).GetComponent<TMP_Text>().text = achievement.Title; ((Component)val.Find("description")).GetComponent<TMP_Text>().text = achievement.Description; LocalAudioPlayer.Play2dOneShot(new AudioReference(FusionMonoDiscReferences.UITurnOnReference), LocalAudioPlayer.InHeadSettings); PooleeHelper.DespawnDelayed(poolee, 5.1f); }); } internal static bool IsPlayingPopup() { return TimeUtilities.TimeSinceStartup - _timeOfPopup <= 5.1f; } internal static void OnInitializeMelon() { LabFusion.SDK.Achievements.Achievement.OnAchievementCompleted += Send; } internal static void OnUpdate() { if (_queuedAchievements.Count > 0 && FusionSceneManager.HasTargetLoaded() && !FusionSceneManager.IsDelayedLoading() && RigData.HasPlayer && !IsPlayingPopup()) { DequeueAchievement(); } } } public static class BitPopup { private static readonly Queue<int> _bitQueue = new Queue<int>(); public const float DefaultDuration = 1f; public static readonly Vector3 LocalPosition = new Vector3(0.319f, -0.198f, 0.783f); public static readonly Quaternion LocalRotation = Quaternion.Euler(0f, 17.252f, 0f); internal static void OnUpdate() { if (FusionSceneManager.HasTargetLoaded() && !FusionSceneManager.IsDelayedLoading() && RigData.HasPlayer && _bitQueue.Count > 0) { DequeueBit(); } } public static void Send(int amount) { if (amount != 0) { _bitQueue.Enqueue(amount); } } private static void DequeueBit() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) int amount = _bitQueue.Dequeue(); Transform camera = ((Rig)RigData.Refs.ControllerRig).m_head; Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(FusionSpawnableReferences.BitPopupReference); LocalAssetSpawner.Register(spawnable); LocalAssetSpawner.Spawn(spawnable, Vector3.zero, Quaternion.identity, delegate(Poolee poolee) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or mi
Plugins/LabFusionUpdater.dll
Decompiled a month agousing System; using System.Diagnostics; using System.Drawing; using System.IO; using System.Net.Http; using System.Net.Security; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; using LabFusionUpdater; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("LabFusion Updater")] [assembly: AssemblyProduct("LabFusion Updater")] [assembly: AssemblyCopyright("Created by Lakatrazz")] [assembly: AssemblyFileVersion("1.1.0")] [assembly: NeutralResourcesLanguage("en")] [assembly: MelonInfo(typeof(FusionUpdaterPlugin), "LabFusion Updater", "1.1.0", "Lakatrazz", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyVersion("1.1.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 LabFusionUpdater { public class FusionUpdaterPlugin : MelonPlugin { public const string Name = "LabFusion Updater"; public const string Author = "Lakatrazz"; public const string Version = "1.1.0"; private MelonPreferences_Category _prefCategory = MelonPreferences.CreateCategory("LabFusionUpdater"); private MelonPreferences_Entry<bool> _offlineModePref; public const string ModName = "LabFusion"; public const string PluginName = "LabFusionUpdater"; public const string FileExtension = ".dll"; public static readonly string ModAssemblyPath = Path.Combine(MelonEnvironment.ModsDirectory, "LabFusion.dll"); public static readonly string PluginAssemblyPath = Path.Combine(MelonEnvironment.PluginsDirectory, "LabFusionUpdater.dll"); public static FusionUpdaterPlugin Instance { get; private set; } public static Instance Logger { get; private set; } public static Assembly UpdaterAssembly { get; private set; } public bool IsOffline => _offlineModePref.Value; public override void OnPreInitialization() { Instance = this; Logger = ((MelonBase)this).LoggerInstance; UpdaterAssembly = ((MelonBase)this).MelonAssembly.Assembly; _offlineModePref = _prefCategory.CreateEntry<bool>("OfflineMode", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _prefCategory.SaveToFile(false); ((MelonBase)this).LoggerInstance.Msg(IsOffline ? Color.Yellow : Color.Green, IsOffline ? "Fusion Auto-Updater is OFFLINE." : "Fusion Auto-Updater is ONLINE."); if (IsOffline) { if (!File.Exists(ModAssemblyPath)) { ((MelonBase)this).LoggerInstance.Warning("LabFusion.dll was not found in the Mods folder!"); ((MelonBase)this).LoggerInstance.Warning("Download it from the Github or switch to ONLINE mode."); ((MelonBase)this).LoggerInstance.Warning("https://github.com/Lakatrazz/BONELAB-Fusion/releases"); } } else { Updater.UpdateMod(); } } } public static class Updater { public enum ExitResult { Success, UpToDate, Error } public const string ReleasesApi = "https://api.github.com/repos/Lakatrazz/BONELAB-Fusion/releases"; public const string ModName = "LabFusion"; public const string AssemblyExtension = ".dll"; public const string ModFileName = "LabFusion.dll"; public const string AcceptHeaderName = "Accept"; public const string AcceptHeaderValue = "application/vnd.github.v3.raw"; public const string UserAgentHeaderName = "User-Agent"; public const string UserAgentHeaderValue = "LabFusionUpdater"; public static void UpdateMod() { Version version = new Version(0, 0, 0); if (File.Exists(FusionUpdaterPlugin.ModAssemblyPath)) { AssemblyName assemblyName = AssemblyName.GetAssemblyName(FusionUpdaterPlugin.ModAssemblyPath); version = new Version(assemblyName.Version.Major, assemblyName.Version.Minor, assemblyName.Version.Build); FusionUpdaterPlugin.Logger.Msg($"{"LabFusion"}{".dll"} found in Mods folder. Version: {version}"); } try { switch (DownloadMod(version, FusionUpdaterPlugin.ModAssemblyPath)) { case ExitResult.Success: ((MelonBase)FusionUpdaterPlugin.Instance).LoggerInstance.Msg("LabFusion.dll updated successfully!"); break; case ExitResult.UpToDate: ((MelonBase)FusionUpdaterPlugin.Instance).LoggerInstance.Msg("LabFusion.dll is already up to date."); break; case ExitResult.Error: ((MelonBase)FusionUpdaterPlugin.Instance).LoggerInstance.Error("LabFusion.dll failed to update!"); break; } } catch (Exception ex) { FusionUpdaterPlugin.Logger.Error("Exception caught while running LabFusion updater!"); FusionUpdaterPlugin.Logger.Error(ex.ToString()); } } private static ExitResult DownloadMod(Version currentVersion, string modAssemblyPath) { using (new HttpClient()) { using HttpClient httpClient = new HttpClient(new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Manual, ServerCertificateCustomValidationCallback = (HttpRequestMessage _, X509Certificate2? _, X509Chain? _, SslPolicyErrors _) => true }); httpClient.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3.raw"); httpClient.DefaultRequestHeaders.Add("User-Agent", "LabFusionUpdater"); try { using StreamReader streamReader = new StreamReader(httpClient.Send(new HttpRequestMessage(HttpMethod.Get, "https://api.github.com/repos/Lakatrazz/BONELAB-Fusion/releases")).Content.ReadAsStream(), Encoding.UTF8); JsonNode? jsonNode = JsonSerializer.Deserialize<JsonNode>(streamReader.ReadToEnd()); Version version = new Version(0, 0, 0); JsonNode jsonNode2 = null; foreach (JsonNode item in jsonNode.AsArray()) { Version version2 = new Version(((string?)item["tag_name"]).Replace("v", "")); if (version2 >= version) { version = version2; jsonNode2 = item; } } Console.WriteLine($"Latest version of {"LabFusion"} is {version}."); if (version <= currentVersion) { return ExitResult.UpToDate; } Console.WriteLine("Downloading latest version..."); bool flag = false; foreach (JsonNode item2 in jsonNode2["assets"].AsArray()) { if (item2["name"].ToString() == "LabFusion.dll") { string requestUri = item2["browser_download_url"].ToString(); HttpResponseMessage httpResponseMessage = httpClient.Send(new HttpRequestMessage(HttpMethod.Get, requestUri)); using FileStream destination = new FileStream(modAssemblyPath, FileMode.Create, FileAccess.Write); httpResponseMessage.Content.ReadAsStream().CopyTo(destination); flag = true; } } if (flag) { return ExitResult.Success; } return ExitResult.Error; } catch (Exception ex) { Console.WriteLine("Exception caught while running LabFusion updater!"); Console.WriteLine(ex.ToString()); return ExitResult.Error; } } } } }