using 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(); 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> ItemDictionaryRef = AccessTools.FieldRefAccess>("itemDictionary"); private static readonly FieldRef ItemPrefabRef = AccessTools.FieldRefAccess("prefab"); private static readonly FieldRef ItemDisabledRef = AccessTools.FieldRefAccess("disabled"); private static readonly FieldRef> PlayerGrabbingRef = AccessTools.FieldRefAccess>("playerGrabbing"); private static readonly FieldRef ChargingStationChargeAreaRef = AccessTools.FieldRefAccess("chargeArea"); public static Dictionary 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 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 Loot = new List(); 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 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() == (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(); 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() == (Object)null) { ((Component)val).gameObject.AddComponent(); 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(); _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() : null); if (!((Object)(object)val == (Object)null)) { PhysGrabObject component = ((Component)val).GetComponent(); 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(); 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() : null); EmpressMysteryBoxPlugin.RaiseMysteryBoxEvent(((Object)((Component)this).gameObject).name, ((Object)(object)val3 != (Object)null) ? val3.ViewID : 0); } else { val2 = Object.Instantiate(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(); 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(); 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(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(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(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(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(true); for (int l = 0; l < componentsInChildren4.Length; l++) { if ((Object)(object)componentsInChildren4[l] != (Object)null) { Object.Destroy((Object)(object)componentsInChildren4[l]); } } } } }