Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Mystery Box v2.0.0
EmpressMysteryBox.dll
Decompiled 5 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Omniscye / Empress")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("3.2.0.0")] [assembly: AssemblyInformationalVersion("3.2.0")] [assembly: AssemblyProduct("EmpressMysteryBox")] [assembly: AssemblyTitle("EmpressMysteryBox")] [assembly: AssemblyVersion("3.2.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Empress.REPO.MysteryBox { [BepInPlugin("com.empress.repo.mysterybox", "Empress Mystery Box", "3.2.0")] public sealed class EmpressMysteryBoxPlugin : BaseUnityPlugin, IOnEventCallback { public const string PluginGuid = "com.empress.repo.mysterybox"; public const string PluginName = "Empress Mystery Box"; public const string PluginVersion = "3.2.0"; public const byte MysteryBoxEventCode = 110; private bool _eventsRegistered; private bool _bindingStarted; private int _sceneHandle = -1; internal static EmpressMysteryBoxPlugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); Log.LogInfo((object)"Empress Mystery Box v3.2.0 loaded."); } private void OnDisable() { if (_eventsRegistered) { PhotonNetwork.RemoveCallbackTarget((object)this); _eventsRegistered = false; } } private void Update() { UpdateEventRegistration(); UpdateLevelBinding(); } private void UpdateEventRegistration() { if (PhotonNetwork.InRoom && !_eventsRegistered) { PhotonNetwork.AddCallbackTarget((object)this); _eventsRegistered = true; } else if (!PhotonNetwork.InRoom && _eventsRegistered) { PhotonNetwork.RemoveCallbackTarget((object)this); _eventsRegistered = false; } } private void UpdateLevelBinding() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!MysteryBoxAccess.CanBindToCurrentLevel()) { _bindingStarted = false; _sceneHandle = -1; return; } Scene activeScene = SceneManager.GetActiveScene(); int handle = ((Scene)(ref activeScene)).handle; if (handle != _sceneHandle) { _sceneHandle = handle; _bindingStarted = false; ((MonoBehaviour)this).StopAllCoroutines(); } if (!_bindingStarted) { _bindingStarted = true; ((MonoBehaviour)this).StartCoroutine(MysteryBoxStationBinder.WaitAndBind()); } } public void OnEvent(EventData photonEvent) { if (photonEvent.Code != 110 || !(photonEvent.CustomData is object[] array) || array.Length < 2) { return; } string text = array[0] as string; if (string.IsNullOrEmpty(text)) { return; } GameObject val = GameObject.Find(text); if ((Object)(object)val == (Object)null) { return; } MysteryBoxStationLogic component = val.GetComponent<MysteryBoxStationLogic>(); if (!((Object)(object)component == (Object)null)) { if (((array[1] is int num) ? num : 0) == -1) { component.PlayRollVisuals(); } else { component.StopRollAndShowPrize(); } } } internal static void RaiseMysteryBoxEvent(string stationName, int result) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.InRoom) { RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)1 }; PhotonNetwork.RaiseEvent((byte)110, (object)new object[2] { stationName, result }, val, SendOptions.SendReliable); } } } internal static class MysteryBoxAccess { private static readonly FieldRef<StatsManager, Dictionary<string, Item>> ItemDictionaryRef = AccessTools.FieldRefAccess<StatsManager, Dictionary<string, Item>>("itemDictionary"); private static readonly FieldRef<Item, PrefabRef> ItemPrefabRef = AccessTools.FieldRefAccess<Item, PrefabRef>("prefab"); private static readonly FieldRef<Item, bool> ItemDisabledRef = AccessTools.FieldRefAccess<Item, bool>("disabled"); private static readonly FieldRef<PhysGrabObject, List<PhysGrabber>> PlayerGrabbingRef = AccessTools.FieldRefAccess<PhysGrabObject, List<PhysGrabber>>("playerGrabbing"); private static readonly FieldRef<ChargingStation, Transform> ChargingStationChargeAreaRef = AccessTools.FieldRefAccess<ChargingStation, Transform>("chargeArea"); public static Dictionary<string, Item> GetItemDictionary() { if (!((Object)(object)StatsManager.instance != (Object)null)) { return null; } return ItemDictionaryRef.Invoke(StatsManager.instance); } public static PrefabRef GetItemPrefab(Item item) { if (!((Object)(object)item != (Object)null)) { return null; } return ItemPrefabRef.Invoke(item); } public static bool IsItemDisabled(Item item) { if ((Object)(object)item != (Object)null) { return ItemDisabledRef.Invoke(item); } return false; } public static bool IsGrabbed(PhysGrabObject physGrabObject) { if ((Object)(object)physGrabObject == (Object)null) { return false; } List<PhysGrabber> list = PlayerGrabbingRef.Invoke(physGrabObject); if (list != null) { return list.Count > 0; } return false; } public static Transform GetChargeArea(ChargingStation station) { if ((Object)(object)station == (Object)null) { return null; } Transform val = ChargingStationChargeAreaRef.Invoke(station); if (!((Object)(object)val != (Object)null)) { return ((Component)station).transform.Find("Charge Area"); } return val; } public static bool CanBindToCurrentLevel() { if ((Object)(object)LevelGenerator.Instance == (Object)null) { return false; } RunManager instance = RunManager.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.levelCurrent == (Object)null) { return false; } return !IsBlockedLevel(); } public static bool IsBlockedLevel() { try { if (SemiFunc.MenuLevel() || SemiFunc.RunIsLobbyMenu() || SemiFunc.RunIsTutorial()) { return true; } RunManager instance = RunManager.instance; Level val = (((Object)(object)instance != (Object)null) ? instance.levelCurrent : null); if ((Object)(object)val == (Object)null) { return true; } string text = (val.NarrativeName ?? string.Empty).Trim().ToLowerInvariant(); string text2 = (((Object)val).name ?? string.Empty).Trim().ToLowerInvariant(); return text.Contains("lobby") || text2.Contains("lobby") || text.Contains("menu") || text2.Contains("menu") || text.Contains("splash") || text2.Contains("splash"); } catch { return true; } } } internal sealed class MysteryBoxLootEntry { public GameObject DisplayPrefab; public string NetworkPath; } internal static class MysteryBoxLootPool { private static readonly List<MysteryBoxLootEntry> Loot = new List<MysteryBoxLootEntry>(); public static int Count => Loot.Count; public static MysteryBoxLootEntry RandomEntry() { Populate(); if (Loot.Count <= 0) { return null; } return Loot[Random.Range(0, Loot.Count)]; } public static void Populate() { if (Loot.Count > 0) { return; } Dictionary<string, Item> itemDictionary = MysteryBoxAccess.GetItemDictionary(); if (itemDictionary == null) { return; } foreach (Item value in itemDictionary.Values) { if ((Object)(object)value == (Object)null || MysteryBoxAccess.IsItemDisabled(value)) { continue; } PrefabRef itemPrefab = MysteryBoxAccess.GetItemPrefab(value); if (itemPrefab != null && itemPrefab.IsValid()) { GameObject prefab = itemPrefab.Prefab; string resourcePath = itemPrefab.ResourcePath; if (!((Object)(object)prefab == (Object)null) && !string.IsNullOrEmpty(resourcePath) && !((Object)(object)prefab.GetComponent<PhotonView>() == (Object)null)) { Loot.Add(new MysteryBoxLootEntry { DisplayPrefab = prefab, NetworkPath = resourcePath }); } } } EmpressMysteryBoxPlugin.Log.LogInfo((object)("Empress Mystery Box loot pool populated with " + Loot.Count + " items.")); } } internal static class MysteryBoxStationBinder { public static IEnumerator WaitAndBind() { float timer = 0f; while (((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated) && timer <= 60f) { timer += Time.deltaTime; yield return null; } if ((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated) { yield break; } yield return (object)new WaitForSeconds(1f); ChargingStation[] array = Object.FindObjectsOfType<ChargingStation>(); if (array == null || array.Length == 0) { if (!MysteryBoxAccess.IsBlockedLevel()) { EmpressMysteryBoxPlugin.Log.LogWarning((object)"Empress Mystery Box found no charging station in this level."); } yield break; } foreach (ChargingStation val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)MysteryBoxAccess.GetChargeArea(val) == (Object)null)) { if (((Object)((Component)val).gameObject).name == "ChargingStation(Clone)") { GameObject gameObject = ((Component)val).gameObject; Vector3 position = ((Component)val).transform.position; ((Object)gameObject).name = "EmpressMysteryBoxStation_" + Mathf.Abs(((Vector3)(ref position)).sqrMagnitude).ToString("0.000"); } if ((Object)(object)((Component)val).gameObject.GetComponent<MysteryBoxStationLogic>() == (Object)null) { ((Component)val).gameObject.AddComponent<MysteryBoxStationLogic>(); EmpressMysteryBoxPlugin.Log.LogInfo((object)"Empress Mystery Box bound to charging station."); } } } } } internal sealed class MysteryBoxStationLogic : MonoBehaviour { private bool _busy; private GameObject _ghostModel; private Coroutine _rollCoroutine; private Transform _chargeArea; private ChargingStation _station; private void Start() { _station = ((Component)this).GetComponent<ChargingStation>(); _chargeArea = MysteryBoxAccess.GetChargeArea(_station); MysteryBoxLootPool.Populate(); ((MonoBehaviour)this).StartCoroutine(ScanRoutine()); } private IEnumerator ScanRoutine() { if ((Object)(object)_chargeArea == (Object)null) { yield break; } while (true) { if (SemiFunc.IsMasterClientOrSingleplayer() && !_busy) { TryAcceptValuable(); } yield return (object)new WaitForSeconds(0.2f); } } private void TryAcceptValuable() { //IL_0006: 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) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Collider[] array = Physics.OverlapBox(_chargeArea.position, _chargeArea.lossyScale * 0.5f, _chargeArea.rotation, LayerMask.op_Implicit(SemiFunc.LayerMaskGetPhysGrabObject())); for (int i = 0; i < array.Length; i++) { EnemyValuable val = (((Object)(object)array[i] != (Object)null) ? ((Component)array[i]).GetComponentInParent<EnemyValuable>() : null); if (!((Object)(object)val == (Object)null)) { PhysGrabObject component = ((Component)val).GetComponent<PhysGrabObject>(); if (!((Object)(object)component == (Object)null) && !MysteryBoxAccess.IsGrabbed(component)) { StartMysteryBoxEvent(component); break; } } } } private void StartMysteryBoxEvent(PhysGrabObject obj) { _busy = true; DestroyAcceptedObject(obj); if (PhotonNetwork.InRoom) { EmpressMysteryBoxPlugin.RaiseMysteryBoxEvent(((Object)((Component)this).gameObject).name, -1); } else { PlayRollVisuals(); } ((MonoBehaviour)this).StartCoroutine(ServerProcessRoutine()); } private static void DestroyAcceptedObject(PhysGrabObject obj) { if (!((Object)(object)obj == (Object)null) && !((Object)(object)((Component)obj).gameObject == (Object)null)) { PhotonView component = ((Component)obj).GetComponent<PhotonView>(); if (PhotonNetwork.InRoom && (Object)(object)component != (Object)null) { PhotonNetwork.Destroy(((Component)obj).gameObject); } else { Object.Destroy((Object)(object)((Component)obj).gameObject); } } } private IEnumerator ServerProcessRoutine() { yield return (object)new WaitForSeconds(4.5f); MysteryBoxLootEntry mysteryBoxLootEntry = MysteryBoxLootPool.RandomEntry(); if (mysteryBoxLootEntry != null) { Vector3 val = _chargeArea.position + Vector3.up * 0.5f; GameObject val2; if (PhotonNetwork.InRoom) { val2 = PhotonNetwork.Instantiate(mysteryBoxLootEntry.NetworkPath, val, Quaternion.identity, (byte)0, (object[])null); PhotonView val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<PhotonView>() : null); EmpressMysteryBoxPlugin.RaiseMysteryBoxEvent(((Object)((Component)this).gameObject).name, ((Object)(object)val3 != (Object)null) ? val3.ViewID : 0); } else { val2 = Object.Instantiate<GameObject>(mysteryBoxLootEntry.DisplayPrefab, val, Quaternion.identity); StopRollAndShowPrize(); } yield return ((MonoBehaviour)this).StartCoroutine(PrizeCountdown(val2)); } else if (PhotonNetwork.InRoom) { EmpressMysteryBoxPlugin.RaiseMysteryBoxEvent(((Object)((Component)this).gameObject).name, -999); } else { StopRollAndShowPrize(); } _busy = false; } private IEnumerator PrizeCountdown(GameObject prize) { float timer = 0f; while (timer < 10f) { if ((Object)(object)prize == (Object)null) { yield break; } PhysGrabObject component = prize.GetComponent<PhysGrabObject>(); if ((Object)(object)component != (Object)null && MysteryBoxAccess.IsGrabbed(component)) { yield break; } timer += Time.deltaTime; yield return null; } if (!((Object)(object)prize == (Object)null)) { PhotonView component2 = prize.GetComponent<PhotonView>(); if (PhotonNetwork.InRoom && (Object)(object)component2 != (Object)null) { PhotonNetwork.Destroy(prize); } else { Object.Destroy((Object)(object)prize); } } } public void PlayRollVisuals() { if (_rollCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_rollCoroutine); } _rollCoroutine = ((MonoBehaviour)this).StartCoroutine(RollAnimation()); } public void StopRollAndShowPrize() { if (_rollCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_rollCoroutine); } if ((Object)(object)_ghostModel != (Object)null) { Object.Destroy((Object)(object)_ghostModel); } _rollCoroutine = null; _ghostModel = null; } private IEnumerator RollAnimation() { if ((Object)(object)_chargeArea == (Object)null) { yield break; } MysteryBoxLootPool.Populate(); if (MysteryBoxLootPool.Count == 0) { yield break; } float speed = 0.1f; float elapsed = 0f; float spinAngle = 0f; Vector3 visualPosition = _chargeArea.position + Vector3.up * 0.5f; while (true) { if ((Object)(object)_ghostModel != (Object)null) { Object.Destroy((Object)(object)_ghostModel); } MysteryBoxLootEntry mysteryBoxLootEntry = MysteryBoxLootPool.RandomEntry(); if (mysteryBoxLootEntry != null && (Object)(object)mysteryBoxLootEntry.DisplayPrefab != (Object)null) { spinAngle += 90f; _ghostModel = Object.Instantiate<GameObject>(mysteryBoxLootEntry.DisplayPrefab, visualPosition, Quaternion.Euler(0f, spinAngle, 0f)); StripRuntimeComponents(_ghostModel); } yield return (object)new WaitForSeconds(speed); elapsed += speed; if (elapsed > 3f) { speed += 0.05f; } } } private static void StripRuntimeComponents(GameObject target) { if ((Object)(object)target == (Object)null) { return; } MonoBehaviour[] componentsInChildren = target.GetComponentsInChildren<MonoBehaviour>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { Object.Destroy((Object)(object)componentsInChildren[i]); } } Rigidbody[] componentsInChildren2 = target.GetComponentsInChildren<Rigidbody>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if ((Object)(object)componentsInChildren2[j] != (Object)null) { Object.Destroy((Object)(object)componentsInChildren2[j]); } } Collider[] componentsInChildren3 = target.GetComponentsInChildren<Collider>(true); for (int k = 0; k < componentsInChildren3.Length; k++) { if ((Object)(object)componentsInChildren3[k] != (Object)null) { Object.Destroy((Object)(object)componentsInChildren3[k]); } } Joint[] componentsInChildren4 = target.GetComponentsInChildren<Joint>(true); for (int l = 0; l < componentsInChildren4.Length; l++) { if ((Object)(object)componentsInChildren4[l] != (Object)null) { Object.Destroy((Object)(object)componentsInChildren4[l]); } } } } }