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.VRMK; using Il2CppSteamworks; using Il2CppSystem; using Il2CppSystem.Collections; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using Il2CppUltEvents; using LabFusion; using LabFusion.Audio; 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.Permissions; using LabFusion.Player; using LabFusion.Preferences; using LabFusion.Preferences.Client; using LabFusion.Preferences.Server; using LabFusion.RPC; using LabFusion.Representation; 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.Triggers; using LabFusion.Safety; using LabFusion.Scene; using LabFusion.Senders; using LabFusion.Support; 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.14.2")] [assembly: MelonInfo(typeof(FusionMod), "LabFusion", "1.14.2", "Lakatrazz", null)] [assembly: MelonGame("Stress Level Zero", null)] [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.14.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 = 14; public const short VersionPatch = 2; public const string VersionString = "1.14.2"; } public class FusionMod : MelonMod { public const string ModName = "LabFusion"; public const string ModAuthor = "Lakatrazz"; public const string GameDeveloper = "Stress Level Zero"; public static readonly Version Version = new Version(1, 14, 2); private static bool _hasAutoUpdater = false; 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.LoadModules(FusionAssembly); SupportManager.LoadGameModule(FusionAssembly); } public override void OnLateInitializeMelon() { PersistentAssetCreator.OnLateInitializeMelon(); PlayerAdditionsHelper.OnInitializeMelon(); _hasAutoUpdater = MelonTypeBase.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().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(); TimeReferences.OnEarlyUpdate(); FusionSceneManager.Internal_UpdateScene(); PopupManager.OnUpdate(); NetworkTickManager.OnUpdate(TimeReferences.UnscaledDeltaTime); float deltaTime = TimeReferences.DeltaTime; NetworkPlayerManager.OnUpdate(deltaTime); NetworkEntityManager.OnUpdate(deltaTime); FusionPlayer.OnUpdate(); VoiceHelper.OnVoiceChatUpdate(); InternalLayerHelpers.OnUpdateLayer(); NetworkConnectionManager.OnUpdate(deltaTime); MultiplayerHooking.InvokeOnUpdate(); GamemodeManager.OnUpdate(); DelayUtilities.OnProcessDelays(); } public override void OnFixedUpdate() { TimeReferences.OnEarlyFixedUpdate(); LocalPlayer.OnFixedUpdate(); PDController.OnFixedUpdate(); float fixedDeltaTime = TimeReferences.FixedDeltaTime; NetworkPlayerManager.OnFixedUpdate(fixedDeltaTime); NetworkEntityManager.OnFixedUpdate(fixedDeltaTime); MultiplayerHooking.InvokeOnFixedUpdate(); GamemodeManager.OnFixedUpdate(); } public override void OnLateUpdate() { float deltaTime = TimeReferences.DeltaTime; NetworkPlayerManager.OnLateUpdate(deltaTime); NetworkEntityManager.OnLateUpdate(deltaTime); InternalLayerHelpers.OnLateUpdateLayer(); MultiplayerHooking.InvokeOnLateUpdate(); GamemodeManager.OnLateUpdate(); } } } namespace LabFusion.Voice { public interface IVoiceManager { List 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 _voiceSpeakers = new List(); private IVoiceReceiver _receiver; private bool _hasDisabledVoice = true; public List VoiceSpeakers => _voiceSpeakers; public virtual bool CanTalk => true; public virtual bool CanHear => true; public virtual string[] InputDevices => Array.Empty(); 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(); } 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 OnVoiceEnabled; [HideFromIl2Cpp] public static event Action 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) { float deltaTime = Time.deltaTime; StreamFilter.TickPeak(deltaTime); if (StreamFilter.ReadingQueue.Count <= 0) { _timeSinceInput += 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.ClearValues(); Amplitude = 0f; } [HideFromIl2Cpp] private void GetAudioSource() { AudioSource component = ((Component)this).GetComponent(); if ((Object)(object)component != (Object)null) { AudioSource = component; } else { AudioSource = CreateAudioSource(); } SetSourceSettings(); } [HideFromIl2Cpp] private AudioSource CreateAudioSource() { AudioSource obj = ((Component)this).gameObject.AddComponent(); 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 = LocalAudioPlayer.Vocals; AudioSource.bypassReverbZones = true; AudioSource.reverbZoneMix = 0f; StreamFilter = ((Component)this).gameObject.AddComponent(); AudioSource.clip = AudioInfo.CreateToneClip(); } } public static class VoiceSourceManager { public static List ActiveVoices { get; } = new List(); public static IEnumerable GetVoicesByID(int id) { return ActiveVoices.Where((VoiceSource voice) => voice.ID == id); } public static void EnqueueSample(IEnumerable 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 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.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() { return ClientSettings.VoiceChat.GlobalVolume.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)(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(); } return Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(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 val = new Il2CppStructArray((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 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); } if (sampleCount > 0) { num2 /= (float)sampleCount; } VoiceSourceManager.SetAmplitude(voicesByID, num2); } } private void CheckTalkingTimeout(ref bool isTalking) { if (isTalking) { _lastTalkTime = TimeReferences.TimeSinceStartup; } else { isTalking = TimeReferences.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 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(Assembly assembly, Action 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(((ScannableReference)BacklotReferences.ConstrainerReference).Barcode); if (!((Object)(object)crate == (Object)null)) { if (!((Crate)crate).Pallet.IsInMarrowGame()) { ((Crate)crate).MainAsset = new MarrowAsset("bf9c97bf88c22dc4f981578e75d9aa12"); } Action action = OnConstrainerLoaded; ((CrateT)(object)crate).LoadAsset(Action.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(go, new Vector3(1000f, 1000f, 1000f), QuaternionExtensions.identity); GlobalConstrainer = obj.GetComponent(); 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 _delays = new List(); 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 => TimeReferences.FrameCount == Frame; public FrameBool(bool value) { _value = value; _frame = TimeReferences.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 where TSource : Object where TComponent : class { private readonly Dictionary _cache = new Dictionary((IEqualityComparer?)new UnityComparer()); public ICollection 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 SpawnPoints = new List(); 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 _rootObjectBuffer = new List(); internal static List 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.op_Implicit((Func)((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.op_Implicit((Func)((GameObject g) => (Object)(object)g == (Object)(object)go))); } internal static GameObject GetRootByIndex(string scene, int index, string name) { List 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(); 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 _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 action) { if ((Object)(object)SoftGrabPose != (Object)null) { action?.Invoke(SoftGrabPose); } else { _onSoftGrabLoaded = (Action)Delegate.Combine(_onSoftGrabLoaded, action); } } private static void CreateTextFont() { Il2CppArrayBase val = Resources.FindObjectsOfTypeAll(); 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 componentsInChildren = ((Component)physicsRig).GetComponentsInChildren(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 list = new List(); 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()) && !((Object)(object)gameObject == (Object)(object)physicsRig.knee) && !((Object)(object)gameObject == (Object)(object)physicsRig.feet)) { ImpactProperties val = gameObject.AddComponent(); val.surfaceData = surfaceData; val.decalType = (DecalType)(-1); list.Add(val); } } physicsRig._impactProperties = new Il2CppReferenceArray(list.ToArray()); } } internal static class SafeEvents { internal static void InvokeSafe(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(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(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(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); } } } } 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.op_Implicit((Il2CppArrayBase)(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(); 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 muted = ClientSettings.VoiceChat.Muted; muted.OnValueChanged = (Action)Delegate.Combine(muted.OnValueChanged, new Action(OnMutedChanged)); FusionPref mutedIndicator = ClientSettings.VoiceChat.MutedIndicator; mutedIndicator.OnValueChanged = (Action)Delegate.Combine(mutedIndicator.OnValueChanged, new Action(OnIndicatorChanged)); RenderPipelineManager.beginCameraRendering += Action.op_Implicit((Action)OnBeginCameraRendering); RenderPipelineManager.endCameraRendering += Action.op_Implicit((Action)OnEndCameraRendering); } public static void OnDeinitializeMelon() { FusionPref muted = ClientSettings.VoiceChat.Muted; muted.OnValueChanged = (Action)Delegate.Remove(muted.OnValueChanged, new Action(OnMutedChanged)); FusionPref mutedIndicator = ClientSettings.VoiceChat.MutedIndicator; mutedIndicator.OnValueChanged = (Action)Delegate.Remove(mutedIndicator.OnValueChanged, new Action(OnIndicatorChanged)); RenderPipelineManager.beginCameraRendering -= Action.op_Implicit((Action)OnBeginCameraRendering); RenderPipelineManager.endCameraRendering -= Action.op_Implicit((Action)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 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(); 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(); _indicatorRenderer.enabled = false; if (!((Object)(object)headset == (Object)null)) { _headsetCamera = ((Component)headset).GetComponent(); 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.op_Implicit((Func)((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)Delegate.Combine(LocalPlayer.OnLocalRigCreated, (Action)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(); obj.reloadLevelOnDeath = false; obj.slowMoOnDeath = false; PhysicsRig physicsRig = manager.physicsRig; ((Component)((Rig)physicsRig).m_handLf).gameObject.AddComponent(); ((Component)((Rig)physicsRig).m_elbowLf).gameObject.AddComponent(); ((Component)((Rig)physicsRig).m_shoulderLf).gameObject.AddComponent(); ((Component)((Rig)physicsRig).m_handRt).gameObject.AddComponent(); ((Component)((Rig)physicsRig).m_elbowRt).gameObject.AddComponent(); ((Component)((Rig)physicsRig).m_shoulderRt).gameObject.AddComponent(); physicsRig.feet.gameObject.AddComponent(); ((Component)((Rig)physicsRig).m_head).gameObject.AddComponent(); } } public static void OnExitServer(RigManager manager) { if ((Object)(object)manager == (Object)null) { return; } MuteUIHelper.OnDestroyMuteUI(); manager.physicsRig._impactProperties = new Il2CppReferenceArray(0L); foreach (ImpactProperties componentsInChild in ((Component)manager).GetComponentsInChildren(true)) { Object.Destroy((Object)(object)componentsInChild); } foreach (CollisionSyncer componentsInChild2 in ((Component)manager).GetComponentsInChildren(true)) { Object.Destroy((Object)(object)componentsInChild2); } manager.health._testVisualDamage = false; ((Il2CppObjectBase)manager.health).TryCast().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() != null) { PooleeExtender extender = networkEntity.GetExtender(); if (extender != null && !IsFixture(networkEntity)) { extender.Component.Despawn(); } } } } private static bool IsFixture(NetworkEntity entity) { if (entity.GetExtender() != null) { return true; } return false; } } public static class TimeReferences { public static float DeltaTime { get; private set; } = 1f; public static float UnscaledDeltaTime { get; private set; } = 1f; public static float FixedDeltaTime { get; private set; } = 0.02f; public static float FixedUnscaledDeltaTime { get; private set; } = 0.02f; public static float TimeSinceStartup { get; private set; } = 0f; public static float TimeScale { get; private set; } = 1f; public static int FrameCount { get; private set; } = 0; public static void OnEarlyUpdate() { TimeScale = Time.timeScale; DeltaTime = Time.deltaTime; UnscaledDeltaTime = Time.unscaledDeltaTime; TimeSinceStartup += DeltaTime; FrameCount++; } public static void OnEarlyFixedUpdate() { FixedDeltaTime = Time.fixedDeltaTime; FixedUnscaledDeltaTime = Time.fixedUnscaledDeltaTime; } 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 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 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(); 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(); 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.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; prismaticSFX.audioEvents = Il2CppReferenceArray.op_Implicit(Array.Empty()); prismaticSFX.modulatedClips = Il2CppReferenceArray.op_Implicit(Array.Empty()); AudioLoader.LoadMonoDisc(FusionMonoDiscReferences.LaserPrismaticSFXReference, delegate(AudioClip clip) { prismaticSFX.modulatedClips = Il2CppReferenceArray.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(); 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.op_Implicit((AudioClip[])(object)new AudioClip[1] { clip }); }); AudioLoader.LoadMonoDisc(FusionMonoDiscReferences.LaserRaySpawnReference, delegate(AudioClip clip) { cursor.raySpawn = Il2CppReferenceArray.op_Implicit((AudioClip[])(object)new AudioClip[1] { clip }); }); AudioLoader.LoadMonoDisc(FusionMonoDiscReferences.LaserRayDespawnReference, delegate(AudioClip clip) { cursor.rayDespawn = Il2CppReferenceArray.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(); val.color1 = new Color(1f, 1f, 1f, 0.1294118f); val.color2 = Color.white; PageElementView val2 = ((Component)transform).gameObject.AddComponent(); 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.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.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(); ZoneEvents obj = trigger.AddComponent(); ((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)(object)obj.onZoneEnter).DynamicCalls += Action.op_Implicit((Action)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)(object)obj.onZoneExit).DynamicCalls += Action.op_Implicit((Action)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(true)) { componentsInChild.font = PersistentAssetCreator.Font; } } public static void AddButtonTriggers(Transform root) { foreach (Button componentsInChild in ((Component)root).GetComponentsInChildren