using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.AI; using UnityEngine.Networking; 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("Empress")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EmpressCoin")] [assembly: AssemblyTitle("EmpressCoin")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 EmpressCoin { internal static class EmpressCoinAccess { private delegate bool EmpressRunIsLevelDelegate(); private delegate int EmpressStatGetRunCurrencyDelegate(); private delegate int EmpressStatSetRunCurrencyDelegate(int value); private static readonly MethodInfo EmpressRunIsLevelMethodInfo = AccessTools.Method(typeof(SemiFunc), "RunIsLevel", (Type[])null, (Type[])null); private static readonly MethodInfo EmpressStatGetRunCurrencyMethodInfo = AccessTools.Method(typeof(SemiFunc), "StatGetRunCurrency", (Type[])null, (Type[])null); private static readonly MethodInfo EmpressStatSetRunCurrencyMethodInfo = AccessTools.Method(typeof(SemiFunc), "StatSetRunCurrency", (Type[])null, (Type[])null); private static readonly EmpressRunIsLevelDelegate EmpressRunIsLevelMethod = ((EmpressRunIsLevelMethodInfo != null) ? AccessTools.MethodDelegate(EmpressRunIsLevelMethodInfo, (object)null, false) : null); private static readonly EmpressStatGetRunCurrencyDelegate EmpressStatGetRunCurrencyMethod = ((EmpressStatGetRunCurrencyMethodInfo != null) ? AccessTools.MethodDelegate(EmpressStatGetRunCurrencyMethodInfo, (object)null, false) : null); private static readonly EmpressStatSetRunCurrencyDelegate EmpressStatSetRunCurrencyMethod = ((EmpressStatSetRunCurrencyMethodInfo != null) ? AccessTools.MethodDelegate(EmpressStatSetRunCurrencyMethodInfo, (object)null, false) : null); private static readonly FieldInfo EmpressLevelGeneratorGeneratedField = AccessTools.Field(typeof(LevelGenerator), "Generated"); private static readonly FieldInfo EmpressLevelPointInStartRoomField = AccessTools.Field(typeof(LevelPoint), "inStartRoom"); private static readonly FieldInfo EmpressLevelPointRoomField = AccessTools.Field(typeof(LevelPoint), "Room"); private static readonly FieldInfo EmpressLevelPointConnectedPointsField = AccessTools.Field(typeof(LevelPoint), "ConnectedPoints"); private static readonly FieldInfo EmpressRoomVolumeTruckField = AccessTools.Field(typeof(RoomVolume), "Truck"); private static readonly FieldInfo EmpressRoomVolumeExtractionField = AccessTools.Field(typeof(RoomVolume), "Extraction"); private static readonly FieldInfo EmpressPlayerAvatarDisabledField = AccessTools.Field(typeof(PlayerAvatar), "isDisabled"); internal static bool EmpressIsRunLevel() { try { return EmpressRunIsLevelMethod != null && EmpressRunIsLevelMethod(); } catch { return false; } } internal static int EmpressGetRunCurrency() { try { return (EmpressStatGetRunCurrencyMethod != null) ? EmpressStatGetRunCurrencyMethod() : 0; } catch { return 0; } } internal static int EmpressSetRunCurrency(int value) { try { return (EmpressStatSetRunCurrencyMethod != null) ? EmpressStatSetRunCurrencyMethod(value) : EmpressGetRunCurrency(); } catch { return EmpressGetRunCurrency(); } } internal static bool EmpressLevelGenerated(LevelGenerator generator) { if ((Object)(object)generator != (Object)null) { return EmpressGetFieldValue(EmpressLevelGeneratorGeneratedField, generator, fallback: false); } return false; } internal static bool EmpressIsStartRoomPoint(LevelPoint point) { if ((Object)(object)point != (Object)null) { return EmpressGetFieldValue(EmpressLevelPointInStartRoomField, point, fallback: false); } return false; } internal static RoomVolume EmpressGetRoom(LevelPoint point) { if (!((Object)(object)point != (Object)null)) { return null; } return EmpressGetFieldValue(EmpressLevelPointRoomField, point, null); } internal static List EmpressGetConnectedPoints(LevelPoint point) { if (!((Object)(object)point != (Object)null)) { return new List(); } return EmpressGetFieldValue>(EmpressLevelPointConnectedPointsField, point, null) ?? new List(); } internal static bool EmpressRoomIsTruck(RoomVolume room) { if ((Object)(object)room != (Object)null) { return EmpressGetFieldValue(EmpressRoomVolumeTruckField, room, fallback: false); } return false; } internal static bool EmpressRoomIsExtraction(RoomVolume room) { if ((Object)(object)room != (Object)null) { return EmpressGetFieldValue(EmpressRoomVolumeExtractionField, room, fallback: false); } return false; } internal static bool EmpressPlayerDisabled(PlayerAvatar avatar) { if (!((Object)(object)avatar == (Object)null)) { return EmpressGetFieldValue(EmpressPlayerAvatarDisabledField, avatar, fallback: false); } return true; } internal static Scene EmpressActiveScene() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return SceneManager.GetActiveScene(); } internal static T EmpressFindFirstSceneObject() where T : Object { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) Scene val = EmpressActiveScene(); T[] array = Resources.FindObjectsOfTypeAll(); foreach (T val2 in array) { if ((Object)(object)val2 == (Object)null) { continue; } T val3 = val2; object obj = val3; Component val4 = (Component)((obj is Component) ? obj : null); if (val4 == null) { object obj2 = val3; GameObject val5 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (val5 != null && val5.scene == val) { return val2; } } else if (val4.gameObject.scene == val) { return val2; } } return default(T); } internal static List EmpressFindSceneObjects() where T : Object { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) Scene val = EmpressActiveScene(); List list = new List(); T[] array = Resources.FindObjectsOfTypeAll(); foreach (T val2 in array) { if ((Object)(object)val2 == (Object)null) { continue; } T val3 = val2; object obj = val3; Component val4 = (Component)((obj is Component) ? obj : null); if (val4 == null) { object obj2 = val3; GameObject val5 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (val5 != null && val5.scene == val) { list.Add(val2); } } else if (val4.gameObject.scene == val) { list.Add(val2); } } return list; } internal static PlayerAvatar EmpressFindLocalPlayer() { List list = EmpressCoinAccess.EmpressFindSceneObjects(); if (PhotonNetwork.InRoom) { foreach (PlayerAvatar item in list) { if (!EmpressPlayerDisabled(item)) { PhotonView val = (((Object)(object)item.photonView != (Object)null) ? item.photonView : ((Component)item).GetComponent()); if ((Object)(object)val != (Object)null && val.IsMine) { return item; } } } } foreach (PlayerAvatar item2 in list) { if (!EmpressPlayerDisabled(item2)) { return item2; } } return null; } internal static PlayerAvatar EmpressFindPlayerByPhotonViewId(int photonViewId) { if (photonViewId <= 0) { return null; } foreach (PlayerAvatar item in EmpressCoinAccess.EmpressFindSceneObjects()) { PhotonView val = (((Object)(object)item.photonView != (Object)null) ? item.photonView : ((Component)item).GetComponent()); if ((Object)(object)val != (Object)null && val.ViewID == photonViewId) { return item; } } return null; } private static T EmpressGetFieldValue(FieldInfo fieldInfo, object instance, T fallback) { if (fieldInfo == null || instance == null) { return fallback; } try { object value = fieldInfo.GetValue(instance); if (value is T) { return (T)value; } } catch { } return fallback; } } internal sealed class EmpressCoinAssets { private const string EmpressBundleName = "coin"; private const string EmpressPrefabName = "BoingImACoin"; private static readonly string[] EmpressBundleCandidates = new string[4] { "coin", "coin.bundle", "coin.unity3d", "coin.assets" }; private static readonly string[] EmpressPreferredSoundCandidates = new string[5] { "EmpressCoinPickup.bin", "EmpressCoinPickup.xorbin", "coinpickup.bin", "coin-pickup.bin", "pickup.bin" }; private readonly EmpressCoinPlugin empressPlugin; private readonly string empressAssemblyDirectory; private AssetBundle empressBundle; private GameObject empressCoinPrefab; private AudioClip empressPickupClip; private Coroutine empressSoundLoadRoutine; private bool empressBundleResolved; private bool empressSoundResolved; internal float EmpressFloorOffset { get; private set; } internal float EmpressHeight { get; private set; } internal float EmpressRadius { get; private set; } internal bool EmpressHasPrefab => (Object)(object)empressCoinPrefab != (Object)null; internal EmpressCoinAssets(EmpressCoinPlugin plugin) { empressPlugin = plugin; empressAssemblyDirectory = Path.GetDirectoryName(typeof(EmpressCoinPlugin).Assembly.Location) ?? AppDomain.CurrentDomain.BaseDirectory; EmpressFloorOffset = 0.05f; EmpressHeight = 0.6f; EmpressRadius = 0.25f; } internal bool EmpressEnsureBundle() { if (empressBundleResolved) { return (Object)(object)empressCoinPrefab != (Object)null; } empressBundleResolved = true; string text = EmpressResolveBundlePath(); if (string.IsNullOrWhiteSpace(text)) { empressPlugin.EmpressWarn("asset bundle 'coin' was not found. EmpressCoin will stay inactive until the bundle is placed beside the DLL or in an assets folder."); return false; } try { empressBundle = AssetBundle.LoadFromFile(text); } catch (Exception ex) { empressPlugin.EmpressWarn("asset bundle load failed: " + ex.Message); return false; } if ((Object)(object)empressBundle == (Object)null) { empressPlugin.EmpressWarn("asset bundle 'coin' could not be opened."); return false; } empressCoinPrefab = empressBundle.LoadAsset("BoingImACoin"); if ((Object)(object)empressCoinPrefab == (Object)null) { empressPlugin.EmpressWarn("asset bundle 'coin' did not contain prefab 'BoingImACoin'."); return false; } EmpressMeasurePrefab(); empressPlugin.EmpressDebug("assets ready from bundle '" + Path.GetFileName(text) + "'."); return true; } internal void EmpressWarmupSound(MonoBehaviour host) { if (!((Object)(object)host == (Object)null) && !empressSoundResolved && empressSoundLoadRoutine == null) { empressSoundLoadRoutine = host.StartCoroutine(EmpressLoadSoundAsync()); } } internal GameObject EmpressInstantiateCoin(Transform parent, Vector3 position, Quaternion rotation) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (!EmpressEnsureBundle()) { return null; } GameObject val = Object.Instantiate(empressCoinPrefab, position, rotation, parent); ((Object)val).name = "EmpressCoin.Actor"; Rigidbody[] componentsInChildren = val.GetComponentsInChildren(true); foreach (Rigidbody obj in componentsInChildren) { obj.isKinematic = true; obj.useGravity = false; obj.velocity = Vector3.zero; obj.angularVelocity = Vector3.zero; } return val; } internal void EmpressPlayPickupSound(Vector3 position, float volume) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown if (!((Object)(object)empressPickupClip == (Object)null) && !(volume <= 0f)) { GameObject val = new GameObject("EmpressCoin.PickupAudio") { hideFlags = (HideFlags)61 }; val.transform.position = position; AudioSource obj = val.AddComponent(); obj.playOnAwake = false; obj.spatialBlend = 1f; obj.rolloffMode = (AudioRolloffMode)1; obj.minDistance = 1f; obj.maxDistance = 18f; obj.volume = Mathf.Clamp01(volume); obj.clip = empressPickupClip; obj.Play(); Object.Destroy((Object)val, Mathf.Max(0.25f, empressPickupClip.length + 0.25f)); } } private void EmpressMeasurePrefab() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(empressCoinPrefab); ((Object)val).hideFlags = (HideFlags)61; val.transform.position = Vector3.zero; val.transform.rotation = Quaternion.identity; val.transform.localScale = Vector3.one; val.SetActive(true); Bounds bounds = default(Bounds); ((Bounds)(ref bounds))..ctor(Vector3.zero, Vector3.zero); bool flag = false; Renderer[] componentsInChildren = val.GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren) { if (!flag) { bounds = val2.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val2.bounds); } } Collider[] componentsInChildren2 = val.GetComponentsInChildren(true); foreach (Collider val3 in componentsInChildren2) { if (!flag) { bounds = val3.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val3.bounds); } } if (flag) { EmpressFloorOffset = Mathf.Max(0.02f, 0f - ((Bounds)(ref bounds)).min.y + 0.01f); EmpressHeight = Mathf.Max(0.2f, ((Bounds)(ref bounds)).size.y); EmpressRadius = Mathf.Max(0.15f, Mathf.Max(((Bounds)(ref bounds)).extents.x, ((Bounds)(ref bounds)).extents.z)); } Object.Destroy((Object)(object)val); } private IEnumerator EmpressLoadSoundAsync() { empressSoundResolved = true; string text = EmpressResolveSoundPath(); if (string.IsNullOrWhiteSpace(text) || !File.Exists(text)) { empressSoundLoadRoutine = null; empressPlugin.EmpressDebug("pickup sound container was not found. Coins will stay silent."); yield break; } byte[] encryptedBytes; try { encryptedBytes = File.ReadAllBytes(text); } catch (Exception ex) { empressSoundLoadRoutine = null; empressPlugin.EmpressWarn("pickup sound container could not be read: " + ex.Message); yield break; } if (encryptedBytes.Length == 0) { empressSoundLoadRoutine = null; empressPlugin.EmpressWarn("pickup sound container was empty."); yield break; } string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); foreach (byte[] item in EmpressBuildXorKeys(fileNameWithoutExtension)) { byte[] bytes = EmpressXorBytes(encryptedBytes, item); if (EmpressTryCreateWavClip(bytes, "EmpressCoin.Pickup", out var clip)) { empressPickupClip = clip; empressSoundLoadRoutine = null; empressPlugin.EmpressDebug("pickup sound ready from XOR container."); yield break; } if (!EmpressTryDetectCompressedAudio(bytes, out var extension, out var audioType)) { continue; } string tempPath = Path.Combine(Path.GetTempPath(), "EmpressCoin_Pickup_" + Guid.NewGuid().ToString("N") + extension); try { File.WriteAllBytes(tempPath, bytes); } catch (Exception ex2) { empressPlugin.EmpressWarn("pickup sound could not be staged for decode: " + ex2.Message); continue; } UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(new Uri(tempPath).AbsoluteUri, audioType); try { yield return request.SendWebRequest(); try { if ((int)request.result == 1) { empressPickupClip = DownloadHandlerAudioClip.GetContent(request); } } finally { EmpressDeleteTempFile(tempPath); } } finally { ((IDisposable)request)?.Dispose(); } if ((Object)(object)empressPickupClip != (Object)null) { ((Object)empressPickupClip).name = "EmpressCoin.Pickup"; empressSoundLoadRoutine = null; empressPlugin.EmpressDebug("pickup sound ready from XOR container."); yield break; } } empressSoundLoadRoutine = null; empressPlugin.EmpressWarn("pickup sound decode failed. Coin pickups will continue without audio."); } private string EmpressResolveBundlePath() { foreach (string item in EmpressEnumerateAssetDirectories()) { string[] empressBundleCandidates = EmpressBundleCandidates; foreach (string path in empressBundleCandidates) { string text = Path.Combine(item, path); if (File.Exists(text)) { return text; } } empressBundleCandidates = Directory.GetFiles(item); foreach (string text2 in empressBundleCandidates) { if (string.Equals(Path.GetFileName(text2), "coin", StringComparison.OrdinalIgnoreCase) || string.Equals(Path.GetFileNameWithoutExtension(text2), "coin", StringComparison.OrdinalIgnoreCase)) { return text2; } } } return null; } private string EmpressResolveSoundPath() { foreach (string item in EmpressEnumerateAssetDirectories()) { string[] empressPreferredSoundCandidates = EmpressPreferredSoundCandidates; foreach (string path in empressPreferredSoundCandidates) { string text = Path.Combine(item, path); if (File.Exists(text)) { return text; } } empressPreferredSoundCandidates = Directory.GetFiles(item); foreach (string text2 in empressPreferredSoundCandidates) { string fileName = Path.GetFileName(text2); if ((fileName.EndsWith(".bin", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".xorbin", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".xor", StringComparison.OrdinalIgnoreCase)) && (fileName.IndexOf("coin", StringComparison.OrdinalIgnoreCase) >= 0 || fileName.IndexOf("pickup", StringComparison.OrdinalIgnoreCase) >= 0)) { return text2; } } } return null; } private IEnumerable EmpressEnumerateAssetDirectories() { HashSet seen = new HashSet(StringComparer.OrdinalIgnoreCase); string[] array = new string[3] { empressAssemblyDirectory, Path.Combine(empressAssemblyDirectory, "assets"), Path.Combine(empressAssemblyDirectory, "Assets") }; string[] array2 = array; foreach (string text in array2) { if (!string.IsNullOrWhiteSpace(text)) { string fullPath = Path.GetFullPath(text); if (seen.Add(fullPath) && Directory.Exists(fullPath)) { yield return fullPath; } } } } private static IEnumerable EmpressBuildXorKeys(string stem) { yield return Encoding.UTF8.GetBytes("empress.repo.empresscoin|pickup-sound|v1"); yield return Encoding.UTF8.GetBytes("empress.repo.empresscoin|pickup|v1"); yield return Encoding.UTF8.GetBytes("empress.repo.empresscoin|coin-pickup|v1"); yield return Encoding.UTF8.GetBytes("empress.repo.empresscoin"); if (!string.IsNullOrWhiteSpace(stem)) { yield return Encoding.UTF8.GetBytes("empress.repo.empresscoin|" + stem + "|v1"); } } private static byte[] EmpressXorBytes(byte[] source, byte[] key) { byte[] array = new byte[source.Length]; for (int i = 0; i < source.Length; i++) { array[i] = (byte)(source[i] ^ key[i % key.Length]); } return array; } private static bool EmpressTryDetectCompressedAudio(byte[] bytes, out string extension, out AudioType audioType) { extension = string.Empty; audioType = (AudioType)0; if (bytes.Length < 4) { return false; } if (bytes[0] == 79 && bytes[1] == 103 && bytes[2] == 103 && bytes[3] == 83) { extension = ".ogg"; audioType = (AudioType)14; return true; } if (bytes[0] == 73 && bytes[1] == 68 && bytes[2] == 51) { extension = ".mp3"; audioType = (AudioType)13; return true; } if (bytes[0] == byte.MaxValue && (bytes[1] & 0xE0) == 224) { extension = ".mp3"; audioType = (AudioType)13; return true; } return false; } private static bool EmpressTryCreateWavClip(byte[] bytes, string clipName, out AudioClip clip) { clip = null; if (bytes.Length < 44) { return false; } if (Encoding.ASCII.GetString(bytes, 0, 4) != "RIFF" || Encoding.ASCII.GetString(bytes, 8, 4) != "WAVE") { return false; } short num = 0; short num2 = 0; int num3 = 0; short num4 = 0; int num5 = -1; int num6 = 0; int num7 = 12; while (num7 + 8 <= bytes.Length) { string @string = Encoding.ASCII.GetString(bytes, num7, 4); int num8 = BitConverter.ToInt32(bytes, num7 + 4); num7 += 8; if (num8 < 0 || num7 + num8 > bytes.Length) { return false; } if (@string == "fmt " && num8 >= 16) { num = BitConverter.ToInt16(bytes, num7); num2 = BitConverter.ToInt16(bytes, num7 + 2); num3 = BitConverter.ToInt32(bytes, num7 + 4); num4 = BitConverter.ToInt16(bytes, num7 + 14); } else if (@string == "data") { num5 = num7; num6 = num8; break; } num7 += num8; if (((uint)num8 & (true ? 1u : 0u)) != 0) { num7++; } } if (num2 <= 0 || num3 <= 0 || num5 < 0 || num6 <= 0) { return false; } int num9; float[] array; try { switch (num) { case 1: switch (num4) { case 8: { num9 = num6; array = new float[num9]; for (int m = 0; m < num9; m++) { array[m] = ((float)(int)bytes[num5 + m] - 128f) / 128f; } break; } case 16: { num9 = num6 / 2; array = new float[num9]; for (int k = 0; k < num9; k++) { short num11 = BitConverter.ToInt16(bytes, num5 + k * 2); array[k] = (float)num11 / 32768f; } break; } case 24: { num9 = num6 / 3; array = new float[num9]; for (int l = 0; l < num9; l++) { int num12 = num5 + l * 3; int num13 = bytes[num12] | (bytes[num12 + 1] << 8) | (bytes[num12 + 2] << 16); if (((uint)num13 & 0x800000u) != 0) { num13 |= -16777216; } array[l] = (float)num13 / 8388608f; } break; } case 32: { num9 = num6 / 4; array = new float[num9]; for (int j = 0; j < num9; j++) { int num10 = BitConverter.ToInt32(bytes, num5 + j * 4); array[j] = (float)num10 / 2.1474836E+09f; } break; } default: return false; } goto end_IL_0117; case 3: { if (num4 != 32) { break; } num9 = num6 / 4; array = new float[num9]; for (int i = 0; i < num9; i++) { array[i] = BitConverter.ToSingle(bytes, num5 + i * 4); } goto end_IL_0117; } } return false; end_IL_0117:; } catch { return false; } if (num9 <= 0 || num9 % num2 != 0) { return false; } clip = AudioClip.Create(clipName, num9 / num2, (int)num2, num3, false); clip.SetData(array, 0); return true; } private static void EmpressDeleteTempFile(string path) { try { if (File.Exists(path)) { File.Delete(path); } } catch { } } } internal sealed class EmpressCoinConfig { internal ConfigEntry EmpressEnabled { get; } internal ConfigEntry EmpressDefaultCoinValueK { get; } internal ConfigEntry EmpressCoinDensityPreset { get; } internal ConfigEntry EmpressOptionalAdvancedCoinCountOverride { get; } internal ConfigEntry EmpressPickupRange { get; } internal ConfigEntry EmpressDebugLogging { get; } internal ConfigEntry EmpressOptionalSoundVolume { get; } internal EmpressCoinConfig(ConfigFile config) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown EmpressEnabled = config.Bind("Empress General", "Enabled", true, "Turns EmpressCoin on for host-authoritative scene sessions."); EmpressDefaultCoinValueK = config.Bind("Empress Gameplay", "DefaultCoinValueK", 1, new ConfigDescription("How much team currency each Empress coin grants in K.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 1000), Array.Empty())); EmpressCoinDensityPreset = config.Bind("Empress Gameplay", "CoinDensityPreset", EmpressCoin.EmpressCoinDensityPreset.Max, "Simple Empress coin density preset for host-authoritative spawn counts."); EmpressOptionalAdvancedCoinCountOverride = config.Bind("Empress Gameplay", "OptionalAdvancedCoinCountOverride", 0, new ConfigDescription("If above zero, EmpressCoin uses this exact per-level spawn count instead of the preset.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 250), Array.Empty())); EmpressPickupRange = config.Bind("Empress Gameplay", "PickupRange", 2.1f, new ConfigDescription("Maximum host-validated pickup distance in world units.", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 8f), Array.Empty())); EmpressDebugLogging = config.Bind("Empress Debug", "DebugLogging", false, "Adds concise EmpressCoin debug logs for asset loading, spawn planning, requests, validation, and sync."); EmpressOptionalSoundVolume = config.Bind("Empress Audio", "OptionalSoundVolume", 0.9f, new ConfigDescription("Local pickup sound playback volume.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); } internal EmpressCoinAuthoritySettings EmpressCreateAuthoritySettings(bool assetsReady) { return new EmpressCoinAuthoritySettings(EmpressEnabled.Value && assetsReady, Mathf.Clamp(EmpressDefaultCoinValueK.Value, 1, 1000), EmpressCoinDensityPreset.Value, Mathf.Clamp(EmpressOptionalAdvancedCoinCountOverride.Value, 0, 250), Mathf.Clamp(EmpressPickupRange.Value, 0.5f, 8f)); } } internal enum EmpressCoinDensityPreset : byte { Min, Medium, Max } internal readonly struct EmpressCoinAuthoritySettings : IEquatable { internal bool EmpressEnabled { get; } internal int EmpressCoinValueK { get; } internal EmpressCoinDensityPreset EmpressDensityPreset { get; } internal int EmpressOptionalAdvancedCoinCountOverride { get; } internal float EmpressPickupRange { get; } internal EmpressCoinAuthoritySettings(bool enabled, int coinValueK, EmpressCoinDensityPreset densityPreset, int optionalAdvancedCoinCountOverride, float pickupRange) { EmpressEnabled = enabled; EmpressCoinValueK = coinValueK; EmpressDensityPreset = densityPreset; EmpressOptionalAdvancedCoinCountOverride = optionalAdvancedCoinCountOverride; EmpressPickupRange = pickupRange; } internal int EmpressResolveSpawnCount(int availableSpawnCount) { if (!EmpressEnabled || availableSpawnCount <= 0) { return 0; } if (EmpressOptionalAdvancedCoinCountOverride > 0) { return Mathf.Clamp(EmpressOptionalAdvancedCoinCountOverride, 1, availableSpawnCount); } int num; int num2; float num3; switch (EmpressDensityPreset) { case EmpressCoinDensityPreset.Min: num = 6; num2 = 18; num3 = 0.08f; break; case EmpressCoinDensityPreset.Max: num = 20; num2 = 64; num3 = 0.28f; break; default: num = 12; num2 = 36; num3 = 0.16f; break; } return Mathf.Clamp(Mathf.RoundToInt((float)availableSpawnCount * num3), Mathf.Min(num, availableSpawnCount), Mathf.Min(num2, availableSpawnCount)); } public bool Equals(EmpressCoinAuthoritySettings other) { if (EmpressEnabled == other.EmpressEnabled && EmpressCoinValueK == other.EmpressCoinValueK && EmpressDensityPreset == other.EmpressDensityPreset && EmpressOptionalAdvancedCoinCountOverride == other.EmpressOptionalAdvancedCoinCountOverride) { return Mathf.Abs(EmpressPickupRange - other.EmpressPickupRange) < 0.0001f; } return false; } public override bool Equals(object obj) { if (obj is EmpressCoinAuthoritySettings other) { return Equals(other); } return false; } public override int GetHashCode() { return HashCode.Combine(EmpressEnabled, EmpressCoinValueK, (byte)EmpressDensityPreset, EmpressOptionalAdvancedCoinCountOverride, Mathf.RoundToInt(EmpressPickupRange * 1000f)); } } internal readonly struct EmpressCoinSpawnPoint { internal int EmpressCoinId { get; } internal Vector3 EmpressPosition { get; } internal float EmpressYaw { get; } internal EmpressCoinSpawnPoint(int coinId, Vector3 position, float yaw) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) EmpressCoinId = coinId; EmpressPosition = position; EmpressYaw = yaw; } } internal sealed class EmpressCoinSceneCoin : MonoBehaviour { internal int EmpressCoinId; internal float EmpressNextRequestTime; internal Vector3 EmpressPickupPosition; private void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) EmpressPickupPosition = ((Component)this).transform.position; } } internal static class EmpressCoinWire { private const string EmpressVersion = "1"; internal static string EmpressSerializeConfig(EmpressCoinAuthoritySettings settings) { return string.Join("|", "1", settings.EmpressEnabled ? "1" : "0", settings.EmpressCoinValueK.ToString(CultureInfo.InvariantCulture), ((byte)settings.EmpressDensityPreset).ToString(CultureInfo.InvariantCulture), settings.EmpressOptionalAdvancedCoinCountOverride.ToString(CultureInfo.InvariantCulture), settings.EmpressPickupRange.ToString("0.###", CultureInfo.InvariantCulture)); } internal static bool EmpressTryParseConfig(string value, out EmpressCoinAuthoritySettings settings) { settings = default(EmpressCoinAuthoritySettings); if (string.IsNullOrWhiteSpace(value)) { return false; } string[] array = value.Split('|'); if (array.Length != 6 || array[0] != "1") { return false; } if (!int.TryParse(array[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return false; } if (!byte.TryParse(array[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2)) { return false; } if (!int.TryParse(array[4], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result3)) { return false; } if (!float.TryParse(array[5], NumberStyles.Float, CultureInfo.InvariantCulture, out var result4)) { return false; } settings = new EmpressCoinAuthoritySettings(array[1] == "1", Mathf.Clamp(result, 1, 1000), (EmpressCoinDensityPreset)((!Enum.IsDefined(typeof(EmpressCoinDensityPreset), result2)) ? 1 : result2), Mathf.Clamp(result3, 0, 250), Mathf.Clamp(result4, 0.5f, 8f)); return true; } internal static string EmpressSerializeSpawn(string sessionToken, string sceneName, IReadOnlyList spawns) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("1").Append('|').Append(sessionToken ?? string.Empty) .Append('|') .Append(sceneName ?? string.Empty) .Append('|'); for (int i = 0; i < spawns.Count; i++) { EmpressCoinSpawnPoint empressCoinSpawnPoint = spawns[i]; if (i > 0) { stringBuilder.Append(';'); } stringBuilder.Append(empressCoinSpawnPoint.EmpressCoinId.ToString(CultureInfo.InvariantCulture)).Append(',').Append(empressCoinSpawnPoint.EmpressPosition.x.ToString("0.###", CultureInfo.InvariantCulture)) .Append(',') .Append(empressCoinSpawnPoint.EmpressPosition.y.ToString("0.###", CultureInfo.InvariantCulture)) .Append(',') .Append(empressCoinSpawnPoint.EmpressPosition.z.ToString("0.###", CultureInfo.InvariantCulture)) .Append(',') .Append(empressCoinSpawnPoint.EmpressYaw.ToString("0.###", CultureInfo.InvariantCulture)); } return stringBuilder.ToString(); } internal static bool EmpressTryParseSpawn(string value, out string sessionToken, out string sceneName, out List spawns) { //IL_0107: Unknown result type (might be due to invalid IL or missing references) sessionToken = string.Empty; sceneName = string.Empty; spawns = new List(); if (string.IsNullOrWhiteSpace(value)) { return false; } string[] array = value.Split(new char[1] { '|' }, 4); if (array.Length < 4 || array[0] != "1") { return false; } sessionToken = array[1]; sceneName = array[2]; if (string.IsNullOrWhiteSpace(array[3])) { return true; } string[] array2 = array[3].Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array2.Length; i++) { string[] array3 = array2[i].Split(','); if (array3.Length != 5) { return false; } if (!int.TryParse(array3[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return false; } if (!float.TryParse(array3[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) || !float.TryParse(array3[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3) || !float.TryParse(array3[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result4) || !float.TryParse(array3[4], NumberStyles.Float, CultureInfo.InvariantCulture, out var result5)) { return false; } spawns.Add(new EmpressCoinSpawnPoint(result, new Vector3(result2, result3, result4), result5)); } spawns = spawns.OrderBy((EmpressCoinSpawnPoint spawn) => spawn.EmpressCoinId).ToList(); return true; } internal static string EmpressSerializePicked(string sessionToken, IReadOnlyCollection pickedIds) { string text = ((pickedIds == null || pickedIds.Count == 0) ? string.Empty : string.Join(",", from id in pickedIds orderby id select id.ToString(CultureInfo.InvariantCulture))); return string.Join("|", "1", sessionToken ?? string.Empty, text); } internal static bool EmpressTryParsePicked(string value, out string sessionToken, out HashSet pickedIds) { sessionToken = string.Empty; pickedIds = new HashSet(); if (string.IsNullOrWhiteSpace(value)) { return false; } string[] array = value.Split(new char[1] { '|' }, 3); if (array.Length < 2 || array[0] != "1") { return false; } sessionToken = array[1]; if (array.Length == 2 || string.IsNullOrWhiteSpace(array[2])) { return true; } string[] array2 = array[2].Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array2.Length; i++) { if (int.TryParse(array2[i], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { pickedIds.Add(result); } } return true; } } [BepInPlugin("empress.repo.empresscoin", "EmpressCoin", "1.0.0")] public sealed class EmpressCoinPlugin : BaseUnityPlugin { internal const string PluginGuid = "empress.repo.empresscoin"; internal const string PluginName = "EmpressCoin"; internal const string PluginVersion = "1.0.0"; private float empressNextRuntimeAuditTime; internal static EmpressCoinPlugin Instance { get; private set; } internal static EmpressCoinRuntime Runtime { get; private set; } internal EmpressCoinConfig EmpressConfig { get; private set; } internal ManualLogSource EmpressLog => ((BaseUnityPlugin)this).Logger; private void Awake() { Instance = this; ((Component)this).transform.SetParent((Transform)null, true); ((Object)this).hideFlags = (HideFlags)61; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); EmpressConfig = new EmpressCoinConfig(((BaseUnityPlugin)this).Config); EmpressEnsureRuntime(); EmpressInfo("loaded"); } private void Update() { ((Component)this).transform.SetParent((Transform)null, true); if (!(Time.unscaledTime < empressNextRuntimeAuditTime)) { empressNextRuntimeAuditTime = Time.unscaledTime + 1f; EmpressEnsureRuntime(); } } internal EmpressCoinRuntime EmpressEnsureRuntime() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown List source = (from runtime in Resources.FindObjectsOfTypeAll() where (Object)(object)runtime != (Object)null select runtime).ToList(); EmpressCoinRuntime empressCoinRuntime = source.FirstOrDefault(); foreach (EmpressCoinRuntime item in source.Skip(1)) { if ((Object)(object)item != (Object)null) { Object.Destroy((Object)(object)((Component)item).gameObject); } } if ((Object)(object)empressCoinRuntime == (Object)null) { GameObject val = new GameObject("EmpressCoin.Runtime"); val.transform.SetParent((Transform)null, true); ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)val); empressCoinRuntime = val.AddComponent(); } else { ((Component)empressCoinRuntime).transform.SetParent((Transform)null, true); ((Object)empressCoinRuntime).hideFlags = (HideFlags)61; ((Object)((Component)empressCoinRuntime).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)empressCoinRuntime).gameObject); } Runtime = empressCoinRuntime; Runtime.EmpressBindPlugin(this); return empressCoinRuntime; } internal void EmpressInfo(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[EmpressCoin] " + message)); } internal void EmpressWarn(string message) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[EmpressCoin] " + message)); } internal void EmpressError(string message) { ((BaseUnityPlugin)this).Logger.LogError((object)("[EmpressCoin] " + message)); } internal void EmpressDebug(string message) { if (EmpressConfig != null && EmpressConfig.EmpressDebugLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[EmpressCoin] " + message)); } } } internal sealed class EmpressCoinRelay : MonoBehaviourPunCallbacks, IOnEventCallback { private const string EmpressConfigKey = "empress.coin.cfg"; private const string EmpressSpawnKey = "empress.coin.spawn"; private const string EmpressPickedKey = "empress.coin.picked"; private PhotonView empressPhotonView; private EmpressCoinRuntime empressRuntime; private const byte EmpressPickupRequestEventCode = 189; private const byte EmpressPickupConfirmedEventCode = 190; internal bool EmpressIsReady => (Object)(object)empressPhotonView != (Object)null; internal static EmpressCoinRelay EmpressEnsureAttached(GameObject hostObject, EmpressCoinRuntime runtime) { if ((Object)(object)hostObject == (Object)null || (Object)(object)runtime == (Object)null) { return null; } EmpressCoinRelay empressCoinRelay = hostObject.GetComponent(); if ((Object)(object)empressCoinRelay == (Object)null) { empressCoinRelay = hostObject.AddComponent(); } empressCoinRelay.empressPhotonView = hostObject.GetComponent(); empressCoinRelay.empressRuntime = runtime; return empressCoinRelay; } private void Awake() { empressPhotonView = ((Component)this).GetComponent(); } internal void EmpressAttachRuntime(EmpressCoinRuntime runtime) { empressRuntime = runtime; if ((Object)(object)empressPhotonView == (Object)null) { empressPhotonView = ((Component)this).GetComponent(); } } internal void EmpressRefreshCurrentState() { if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) { EmpressApplyRoomState((IDictionary)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties); } } internal void EmpressPublishSession(EmpressCoinAuthoritySettings settings, string sessionToken, string sceneName, List spawns, HashSet pickedCoins) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && PhotonNetwork.IsMasterClient) { Hashtable val = new Hashtable { [(object)"empress.coin.cfg"] = EmpressCoinWire.EmpressSerializeConfig(settings), [(object)"empress.coin.spawn"] = EmpressCoinWire.EmpressSerializeSpawn(sessionToken, sceneName, spawns), [(object)"empress.coin.picked"] = EmpressCoinWire.EmpressSerializePicked(sessionToken, pickedCoins) }; PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } empressRuntime?.EmpressConsumeSyncedState(settings, sessionToken, sceneName, spawns, pickedCoins); } internal void EmpressPublishPickedState(string sessionToken, HashSet pickedCoins) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && PhotonNetwork.IsMasterClient) { Hashtable val = new Hashtable { [(object)"empress.coin.picked"] = EmpressCoinWire.EmpressSerializePicked(sessionToken, pickedCoins) }; PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } internal void EmpressRequestPickup(int coinId, int requesterPhotonViewId) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0062: Expected O, but got Unknown //IL_0068: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown if (!PhotonNetwork.InRoom) { empressRuntime?.EmpressTryResolvePickupAsAuthority(coinId, requesterPhotonViewId, null); return; } if (PhotonNetwork.IsMasterClient) { empressRuntime?.EmpressTryResolvePickupAsAuthority(coinId, requesterPhotonViewId, PhotonNetwork.LocalPlayer); return; } Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"c", (object)coinId); ((Dictionary)val).Add((object)"v", (object)requesterPhotonViewId); Hashtable val2 = val; PhotonNetwork.RaiseEvent((byte)189, (object)val2, new RaiseEventOptions { Receivers = (ReceiverGroup)2 }, SendOptions.SendReliable); } public override void OnEnable() { ((MonoBehaviourPunCallbacks)this).OnEnable(); PhotonNetwork.AddCallbackTarget((object)this); } public override void OnDisable() { ((MonoBehaviourPunCallbacks)this).OnDisable(); PhotonNetwork.RemoveCallbackTarget((object)this); } void IOnEventCallback.OnEvent(EventData photonEvent) { //IL_01d2: Unknown result type (might be due to invalid IL or missing references) if (photonEvent.Code == 189) { if (!PhotonNetwork.IsMasterClient) { return; } object customData = photonEvent.CustomData; Hashtable val = (Hashtable)((customData is Hashtable) ? customData : null); if (val == null) { return; } object obj = val[(object)"c"]; if (!(obj is int)) { return; } int coinId = (int)obj; obj = val[(object)"v"]; if (!(obj is int)) { return; } int requesterPhotonViewId = (int)obj; Player sender = null; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val2 in playerList) { if (val2.ActorNumber == photonEvent.Sender) { sender = val2; break; } } empressRuntime?.EmpressTryResolvePickupAsAuthority(coinId, requesterPhotonViewId, sender); } else { if (photonEvent.Code != 190 || (PhotonNetwork.InRoom && photonEvent.Sender != PhotonNetwork.MasterClient.ActorNumber)) { return; } object customData2 = photonEvent.CustomData; Hashtable val3 = (Hashtable)((customData2 is Hashtable) ? customData2 : null); if (val3 == null || !(val3[(object)"t"] is string sessionToken)) { return; } object obj = val3[(object)"c"]; if (!(obj is int)) { return; } int coinId2 = (int)obj; obj = val3[(object)"px"]; if (!(obj is float)) { return; } float num = (float)obj; obj = val3[(object)"py"]; if (!(obj is float)) { return; } float num2 = (float)obj; obj = val3[(object)"pz"]; if (!(obj is float)) { return; } float num3 = (float)obj; obj = val3[(object)"r"]; if (obj is int) { int rewardK = (int)obj; obj = val3[(object)"v"]; if (obj is int) { int pickerPhotonViewId = (int)obj; empressRuntime?.EmpressHandlePickupConfirmed(sessionToken, coinId2, new Vector3(num, num2, num3), rewardK, pickerPhotonViewId); } } } } internal void EmpressBroadcastPickupConfirmed(string sessionToken, int coinId, Vector3 pickupPosition, int rewardK, int pickerPhotonViewId) { //IL_000a: 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_001b: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0042: 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_0058: Expected O, but got Unknown //IL_0058: 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_006e: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_0093: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.InRoom) { Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"t", (object)sessionToken); ((Dictionary)val).Add((object)"c", (object)coinId); ((Dictionary)val).Add((object)"px", (object)pickupPosition.x); ((Dictionary)val).Add((object)"py", (object)pickupPosition.y); ((Dictionary)val).Add((object)"pz", (object)pickupPosition.z); ((Dictionary)val).Add((object)"r", (object)rewardK); ((Dictionary)val).Add((object)"v", (object)pickerPhotonViewId); Hashtable val2 = val; PhotonNetwork.RaiseEvent((byte)190, (object)val2, new RaiseEventOptions { Receivers = (ReceiverGroup)1 }, SendOptions.SendReliable); } else { empressRuntime?.EmpressHandlePickupConfirmed(sessionToken, coinId, pickupPosition, rewardK, pickerPhotonViewId); } } [PunRPC] private void EmpressRpcPickupRequest(int coinId, int requesterPhotonViewId, PhotonMessageInfo info) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.IsMasterClient) { empressRuntime?.EmpressTryResolvePickupAsAuthority(coinId, requesterPhotonViewId, info.Sender); } } [PunRPC] private void EmpressRpcPickupConfirmed(string sessionToken, int coinId, Vector3 pickupPosition, int rewardK, int pickerPhotonViewId, PhotonMessageInfo info) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.InRoom || info.Sender == PhotonNetwork.MasterClient) { empressRuntime?.EmpressHandlePickupConfirmed(sessionToken, coinId, pickupPosition, rewardK, pickerPhotonViewId); } } public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { EmpressApplyRoomState((IDictionary)((PhotonNetwork.CurrentRoom != null) ? ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties : propertiesThatChanged)); } public override void OnMasterClientSwitched(Player newMasterClient) { if (PhotonNetwork.LocalPlayer == newMasterClient) { empressRuntime?.EmpressHandleMasterClientSwitch(); } } private void EmpressApplyRoomState(IDictionary roomProperties) { if (roomProperties == null || !roomProperties.Contains("empress.coin.cfg") || !roomProperties.Contains("empress.coin.spawn")) { return; } string value = roomProperties["empress.coin.cfg"] as string; string value2 = roomProperties["empress.coin.spawn"] as string; string value3 = (roomProperties.Contains("empress.coin.picked") ? (roomProperties["empress.coin.picked"] as string) : null); if (EmpressCoinWire.EmpressTryParseConfig(value, out var settings) && EmpressCoinWire.EmpressTryParseSpawn(value2, out var sessionToken, out var sceneName, out var spawns)) { HashSet pickedCoins = new HashSet(); if (!string.IsNullOrWhiteSpace(value3) && EmpressCoinWire.EmpressTryParsePicked(value3, out var sessionToken2, out var pickedIds) && sessionToken2 == sessionToken) { pickedCoins = pickedIds; } empressRuntime?.EmpressConsumeSyncedState(settings, sessionToken, sceneName, spawns, pickedCoins); } } } internal sealed class EmpressCoinRuntime : MonoBehaviour { private static readonly Vector2[] EmpressSpawnProbeOffsets = (Vector2[])(object)new Vector2[9] { Vector2.zero, new Vector2(0.45f, 0f), new Vector2(-0.45f, 0f), new Vector2(0f, 0.45f), new Vector2(0f, -0.45f), new Vector2(0.32f, 0.32f), new Vector2(-0.32f, 0.32f), new Vector2(0.32f, -0.32f), new Vector2(-0.32f, -0.32f) }; private readonly Dictionary empressSceneCoins = new Dictionary(); private readonly Dictionary empressSpawnLookup = new Dictionary(); private readonly List empressSpawnPoints = new List(); private HashSet empressPickedCoins = new HashSet(); private EmpressCoinPlugin empressPlugin; private EmpressCoinAssets empressAssets; private EmpressCoinRelay empressRelay; private Coroutine empressSceneInitRoutine; private GameObject empressSceneRoot; private int empressSceneSerial; private int empressAppliedSceneHandle = -1; private string empressSessionToken = string.Empty; private string empressSceneName = string.Empty; private EmpressCoinAuthoritySettings empressCurrentSettings; private EmpressCoinAuthoritySettings empressPendingSettings; private string empressPendingSessionToken = string.Empty; private string empressPendingSceneName = string.Empty; private List empressPendingSpawns = new List(); private HashSet empressPendingPickedCoins = new HashSet(); private bool empressPendingStateAvailable; private float empressNextRelayAuditTime; private float empressNextPickupScanTime; private int EmpressBlockedSpawnMask => LayerMask.GetMask(new string[2] { "Player", "Enemy" }); private int EmpressFloorSpawnMask { get { int mask = LayerMask.GetMask(new string[1] { "Default" }); if (mask == 0) { return -1; } return mask; } } internal void EmpressBindPlugin(EmpressCoinPlugin plugin) { empressPlugin = plugin; if (empressAssets == null && (Object)(object)empressPlugin != (Object)null) { empressAssets = new EmpressCoinAssets(empressPlugin); } } private void Awake() { ((Component)this).transform.SetParent((Transform)null, true); ((Object)this).hideFlags = (HideFlags)61; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } private void OnEnable() { SceneManager.sceneLoaded += EmpressOnSceneLoaded; EmpressScheduleSceneInit(); } private void OnDisable() { SceneManager.sceneLoaded -= EmpressOnSceneLoaded; } private void Update() { ((Component)this).transform.SetParent((Transform)null, true); ((Object)this).hideFlags = (HideFlags)61; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; if (!((Object)(object)empressPlugin == (Object)null)) { if (Time.unscaledTime >= empressNextRelayAuditTime) { empressNextRelayAuditTime = Time.unscaledTime + 0.25f; EmpressAuditSceneState(); } if (Time.unscaledTime >= empressNextPickupScanTime) { empressNextPickupScanTime = Time.unscaledTime + 0.1f; EmpressScanForLocalPickups(); } } } internal void EmpressConsumeSyncedState(EmpressCoinAuthoritySettings settings, string sessionToken, string sceneName, List spawns, HashSet pickedCoins) { empressPendingSettings = settings; empressPendingSessionToken = sessionToken ?? string.Empty; empressPendingSceneName = sceneName ?? string.Empty; empressPendingSpawns = ((spawns != null) ? new List(spawns.OrderBy((EmpressCoinSpawnPoint spawn) => spawn.EmpressCoinId)) : new List()); empressPendingPickedCoins = ((pickedCoins != null) ? new HashSet(pickedCoins) : new HashSet()); empressPendingStateAvailable = true; EmpressTryApplyPendingState(); } internal void EmpressTryResolvePickupAsAuthority(int coinId, int requesterPhotonViewId, Player sender) { //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) empressPlugin.EmpressDebug("resolve pickup for coin " + coinId + " token=" + (string.IsNullOrWhiteSpace(empressSessionToken) ? "EMPTY" : "SET") + " enabled=" + empressCurrentSettings.EmpressEnabled + " spawnCount=" + empressSpawnLookup.Count + "."); if (string.IsNullOrWhiteSpace(empressSessionToken)) { empressPlugin.EmpressDebug("pickup rejected for coin " + coinId + " because the session token was empty."); return; } if (!empressCurrentSettings.EmpressEnabled) { empressPlugin.EmpressDebug("pickup rejected for coin " + coinId + " because the current session is inactive."); return; } if (empressPickedCoins.Contains(coinId)) { empressPlugin.EmpressDebug("pickup rejected for coin " + coinId + " because it was already collected."); return; } if (!empressSpawnLookup.TryGetValue(coinId, out var value)) { empressPlugin.EmpressDebug("pickup rejected for coin " + coinId + " because no authoritative spawn was found."); return; } PlayerAvatar val = EmpressResolvePickupPlayer(requesterPhotonViewId, sender); if ((Object)(object)val == (Object)null) { empressPlugin.EmpressDebug("pickup rejected for coin " + coinId + " because the requesting player was invalid."); return; } if (EmpressCoinAccess.EmpressPlayerDisabled(val)) { empressPlugin.EmpressDebug("pickup rejected for coin " + coinId + " because the requesting player is disabled."); return; } Vector3 val2 = value.EmpressPosition; if (empressSceneCoins.TryGetValue(coinId, out var value2) && (Object)(object)value2 != (Object)null) { val2 = value2.EmpressPickupPosition; } float num = empressCurrentSettings.EmpressPickupRange + Mathf.Max(0.25f, empressAssets.EmpressRadius); float num2 = Vector3.Distance(((Component)val).transform.position, val2); if (num2 > num) { empressPlugin.EmpressDebug("pickup rejected for coin " + coinId + " because the requester was too far away at " + num2.ToString("0.##", CultureInfo.InvariantCulture) + "."); return; } empressPickedCoins.Add(coinId); int num3 = EmpressCoinAccess.EmpressSetRunCurrency(EmpressCoinAccess.EmpressGetRunCurrency() + empressCurrentSettings.EmpressCoinValueK); empressPlugin.EmpressDebug("pickup validated for coin " + coinId + ". Team currency is now " + num3 + "K."); if ((Object)(object)empressRelay != (Object)null) { empressRelay.EmpressBroadcastPickupConfirmed(empressSessionToken, coinId, val2, empressCurrentSettings.EmpressCoinValueK, requesterPhotonViewId); empressRelay.EmpressPublishPickedState(empressSessionToken, empressPickedCoins); } else { EmpressHandlePickupConfirmed(empressSessionToken, coinId, val2, empressCurrentSettings.EmpressCoinValueK, requesterPhotonViewId); } } internal void EmpressHandlePickupConfirmed(string sessionToken, int coinId, Vector3 pickupPosition, int rewardK, int pickerPhotonViewId) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (!string.Equals(sessionToken, empressSessionToken, StringComparison.Ordinal)) { return; } bool num = empressPickedCoins.Add(coinId); bool flag = EmpressRemoveCoin(coinId); if (num || flag) { if (flag && empressAssets != null && (Object)(object)empressPlugin != (Object)null) { empressAssets.EmpressPlayPickupSound(pickupPosition, empressPlugin.EmpressConfig.EmpressOptionalSoundVolume.Value); } empressPlugin.EmpressDebug("pickup synced for coin " + coinId + " from player view " + pickerPhotonViewId + " with reward " + rewardK + "K."); } } internal void EmpressHandleMasterClientSwitch() { empressPlugin.EmpressInfo("master client changed. EmpressCoin is refreshing the authoritative room state."); empressRelay?.EmpressRefreshCurrentState(); EmpressTryApplyPendingState(); } private void EmpressOnSceneLoaded(Scene scene, LoadSceneMode mode) { EmpressScheduleSceneInit(); } private void EmpressScheduleSceneInit() { empressSceneSerial++; if (empressSceneInitRoutine != null) { ((MonoBehaviour)this).StopCoroutine(empressSceneInitRoutine); empressSceneInitRoutine = null; } empressRelay = null; empressPendingStateAvailable = false; empressPendingSessionToken = string.Empty; empressPendingSceneName = string.Empty; empressPendingSpawns = new List(); empressPendingPickedCoins = new HashSet(); EmpressClearSceneState(); empressSceneInitRoutine = ((MonoBehaviour)this).StartCoroutine(EmpressSceneInitAsync(empressSceneSerial)); } private IEnumerator EmpressSceneInitAsync(int serial) { float timeoutAt = Time.unscaledTime + 30f; while (serial == empressSceneSerial) { if (!EmpressCoinAccess.EmpressIsRunLevel()) { empressSceneInitRoutine = null; yield break; } empressAssets?.EmpressEnsureBundle(); empressAssets?.EmpressWarmupSound((MonoBehaviour)(object)this); EmpressEnsureRelay(); empressRelay?.EmpressRefreshCurrentState(); if (EmpressTryApplyPendingState()) { empressSceneInitRoutine = null; yield break; } LevelGenerator val = EmpressCoinAccess.EmpressFindFirstSceneObject(); if ((Object)(object)val != (Object)null && EmpressCoinAccess.EmpressLevelGenerated(val) && (Object)(object)empressRelay != (Object)null && (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient)) { Scene val2 = EmpressCoinAccess.EmpressActiveScene(); if (empressAppliedSceneHandle != ((Scene)(ref val2)).handle) { EmpressCreateAuthoritativeSceneState(val, ((Scene)(ref val2)).name); } empressSceneInitRoutine = null; yield break; } if (Time.unscaledTime >= timeoutAt) { EmpressCoinPlugin empressCoinPlugin = empressPlugin; Scene val3 = EmpressCoinAccess.EmpressActiveScene(); empressCoinPlugin.EmpressDebug("scene initialization timed out for " + ((Scene)(ref val3)).name + "."); empressSceneInitRoutine = null; yield break; } yield return (object)new WaitForSecondsRealtime(0.25f); } empressSceneInitRoutine = null; } private void EmpressAuditSceneState() { if (!EmpressCoinAccess.EmpressIsRunLevel()) { if (empressAppliedSceneHandle != -1 || empressSceneCoins.Count > 0) { EmpressClearSceneState(); } } else { empressAssets?.EmpressEnsureBundle(); empressAssets?.EmpressWarmupSound((MonoBehaviour)(object)this); EmpressEnsureRelay(); EmpressTryApplyPendingState(); } } private void EmpressEnsureRelay() { empressRelay = EmpressCoinRelay.EmpressEnsureAttached(((Component)this).gameObject, this); empressRelay?.EmpressAttachRuntime(this); } private bool EmpressTryApplyPendingState() { //IL_000a: 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) if (!empressPendingStateAvailable) { return false; } Scene val = EmpressCoinAccess.EmpressActiveScene(); if (!((Scene)(ref val)).IsValid() || !string.Equals(((Scene)(ref val)).name, empressPendingSceneName, StringComparison.Ordinal)) { return false; } LevelGenerator val2 = EmpressCoinAccess.EmpressFindFirstSceneObject(); if ((Object)(object)val2 == (Object)null || !EmpressCoinAccess.EmpressLevelGenerated(val2)) { return false; } if (empressAppliedSceneHandle != ((Scene)(ref val)).handle || !string.Equals(empressSessionToken, empressPendingSessionToken, StringComparison.Ordinal) || !empressCurrentSettings.Equals(empressPendingSettings) || empressSpawnPoints.Count != empressPendingSpawns.Count) { empressSessionToken = empressPendingSessionToken; empressSceneName = empressPendingSceneName; empressCurrentSettings = empressPendingSettings; empressPickedCoins = new HashSet(empressPendingPickedCoins); empressSpawnPoints.Clear(); empressSpawnPoints.AddRange(empressPendingSpawns); empressSpawnLookup.Clear(); foreach (EmpressCoinSpawnPoint empressSpawnPoint in empressSpawnPoints) { empressSpawnLookup[empressSpawnPoint.EmpressCoinId] = empressSpawnPoint; } EmpressRebuildSceneCoins(); empressAppliedSceneHandle = ((Scene)(ref val)).handle; empressPlugin.EmpressDebug("scene sync applied for " + empressSceneName + " with " + empressSceneCoins.Count + " visible coins and " + empressPickedCoins.Count + " picked."); } else { foreach (int item in new HashSet(empressPendingPickedCoins)) { if (empressPickedCoins.Add(item)) { EmpressRemoveCoin(item); } } } empressPendingStateAvailable = false; return true; } private void EmpressCreateAuthoritativeSceneState(LevelGenerator levelGenerator, string sceneName) { if ((Object)(object)levelGenerator == (Object)null || (Object)(object)empressPlugin == (Object)null || (Object)(object)empressRelay == (Object)null) { return; } bool assetsReady = empressAssets != null && empressAssets.EmpressEnsureBundle(); EmpressCoinAuthoritySettings settings = empressPlugin.EmpressConfig.EmpressCreateAuthoritySettings(assetsReady); List list = (settings.EmpressEnabled ? EmpressBuildSpawnPlan(levelGenerator, settings) : new List()); string sessionToken = Guid.NewGuid().ToString("N"); if (settings.EmpressEnabled) { if (list.Count > 0) { empressPlugin.EmpressInfo("scene " + sceneName + " armed with " + list.Count + " coins."); } else { empressPlugin.EmpressWarn("scene " + sceneName + " produced no valid coin placements."); } } empressPlugin.EmpressDebug("host published " + list.Count + " coins for scene " + sceneName + "."); empressRelay.EmpressPublishSession(settings, sessionToken, sceneName, list, new HashSet()); } private List EmpressBuildSpawnPlan(LevelGenerator levelGenerator, EmpressCoinAuthoritySettings settings) { //IL_00d6: 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) List list = (((Object)(object)levelGenerator != (Object)null && levelGenerator.LevelPathPoints != null && levelGenerator.LevelPathPoints.Count > 0) ? levelGenerator.LevelPathPoints.Where((LevelPoint point) => (Object)(object)point != (Object)null).Distinct().ToList() : (from point in EmpressCoinAccess.EmpressFindSceneObjects() where (Object)(object)point != (Object)null select point).Distinct().ToList()).Where((LevelPoint point) => !EmpressCoinAccess.EmpressIsStartRoomPoint(point)).Where(delegate(LevelPoint point) { RoomVolume val = EmpressCoinAccess.EmpressGetRoom(point); return (Object)(object)val != (Object)null && !EmpressCoinAccess.EmpressRoomIsTruck(val) && !EmpressCoinAccess.EmpressRoomIsExtraction(val); }).ToList(); Scene activeScene = SceneManager.GetActiveScene(); Random random = new Random(HashCode.Combine(((Scene)(ref activeScene)).name, list.Count, Time.frameCount, PhotonNetwork.InRoom ? PhotonNetwork.ServerTimestamp : Environment.TickCount)); List list2 = EmpressBuildCandidateSpawnPoints(list, random); int num = settings.EmpressResolveSpawnCount(list2.Count); if (num <= 0 || list2.Count == 0) { return new List(); } float num2 = Mathf.Max(1.35f, empressAssets.EmpressRadius * 3.25f); switch (settings.EmpressDensityPreset) { case EmpressCoinDensityPreset.Min: num2 *= 1.35f; break; case EmpressCoinDensityPreset.Max: num2 *= 0.7f; break; } return EmpressSelectSpawnPoints(list2, num, num2, random); } private List EmpressBuildCandidateSpawnPoints(List eligiblePoints, Random random) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if (eligiblePoints.Count == 0) { return list; } HashSet hashSet = new HashSet(eligiblePoints); foreach (LevelPoint item2 in eligiblePoints.OrderBy((LevelPoint _) => random.Next())) { if (EmpressTryBuildSpawn(((Component)item2).transform.position, random, 1.6f, out var position, out var yaw)) { list.Add(new EmpressCoinSpawnPoint(list.Count, position, yaw)); } } HashSet hashSet2 = new HashSet(); foreach (LevelPoint eligiblePoint in eligiblePoints) { foreach (LevelPoint item3 in EmpressCoinAccess.EmpressGetConnectedPoints(eligiblePoint)) { if (!((Object)(object)item3 == (Object)null) && !((Object)(object)item3 == (Object)(object)eligiblePoint) && hashSet.Contains(item3)) { ulong item = EmpressBuildSegmentKey(eligiblePoint, item3); if (hashSet2.Add(item)) { EmpressAddSegmentCandidates(((Component)eligiblePoint).transform.position, ((Component)item3).transform.position, list, random); } } } } if (list.Count < eligiblePoints.Count * 2) { foreach (LevelPoint item4 in eligiblePoints.OrderBy((LevelPoint _) => random.Next())) { for (int i = 0; i < 2; i++) { double num = random.NextDouble() * Math.PI * 2.0; float num2 = 0.9f + (float)random.NextDouble() * 0.9f; Vector3 anchorSeed = ((Component)item4).transform.position + new Vector3(Mathf.Cos((float)num) * num2, 0f, Mathf.Sin((float)num) * num2); if (EmpressTryBuildSpawn(anchorSeed, random, 1.9f, out var position2, out var yaw2)) { list.Add(new EmpressCoinSpawnPoint(list.Count, position2, yaw2)); } } } } return list; } private void EmpressAddSegmentCandidates(Vector3 from, Vector3 to, List candidates, Random random) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) float num = Vector3.Distance(from, to); if (num < 2.5f) { return; } int num2 = Mathf.Clamp(Mathf.FloorToInt(num / 2.75f), 1, 6); Vector3 val = to - from; Vector3 normalized = ((Vector3)(ref val)).normalized; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(0f - normalized.z, 0f, normalized.x); for (int i = 0; i < num2; i++) { float num3 = ((float)i + 1f) / ((float)num2 + 1f); float num4 = Mathf.Min(0.45f, num * 0.08f); float num5 = ((i % 2 == 0) ? 1f : (-1f)); float num6 = 0.35f + (float)random.NextDouble() * 0.65f; Vector3 anchorSeed = Vector3.Lerp(from, to, num3) + val2 * (num4 * num5 * num6); if (EmpressTryBuildSpawn(anchorSeed, random, 1.45f, out var position, out var yaw)) { candidates.Add(new EmpressCoinSpawnPoint(candidates.Count, position, yaw)); } } } private List EmpressSelectSpawnPoints(List candidates, int targetCount, float minSpacing, Random random) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) List list = candidates.OrderBy((EmpressCoinSpawnPoint _) => random.Next()).ToList(); List list2 = new List(Mathf.Min(targetCount, list.Count)); EmpressSelectSpawnPass(list, list2, targetCount, minSpacing); if (list2.Count < targetCount) { EmpressSelectSpawnPass(list, list2, targetCount, minSpacing * 0.65f); } if (list2.Count < targetCount) { EmpressSelectSpawnPass(list, list2, targetCount, 0.01f); } for (int i = 0; i < list2.Count; i++) { EmpressCoinSpawnPoint empressCoinSpawnPoint = list2[i]; list2[i] = new EmpressCoinSpawnPoint(i, empressCoinSpawnPoint.EmpressPosition, empressCoinSpawnPoint.EmpressYaw); } return list2; } private static void EmpressSelectSpawnPass(List candidates, List selectedSpawns, int targetCount, float minSpacing) { float requiredSpacing = Mathf.Max(0.01f, minSpacing); foreach (EmpressCoinSpawnPoint candidate in candidates) { if (selectedSpawns.Count >= targetCount) { break; } if (!selectedSpawns.Any((EmpressCoinSpawnPoint existing) => Vector3.Distance(existing.EmpressPosition, candidate.EmpressPosition) < requiredSpacing)) { selectedSpawns.Add(candidate); } } } private static ulong EmpressBuildSegmentKey(LevelPoint first, LevelPoint second) { int num = (((Object)(object)first != (Object)null) ? ((Object)first).GetInstanceID() : 0); int num2 = (((Object)(object)second != (Object)null) ? ((Object)second).GetInstanceID() : 0); int num3 = ((num < num2) ? num : num2); uint num4 = (uint)((num < num2) ? num2 : num); return ((ulong)(uint)num3 << 32) | num4; } private bool EmpressTryBuildSpawn(Vector3 anchorSeed, Random random, float navMeshRadius, out Vector3 position, out float yaw) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; yaw = 0f; if (empressAssets == null) { return false; } float num = Mathf.Max(0.35f, empressAssets.EmpressRadius * 1.45f); float num2 = Mathf.Max(4f, empressAssets.EmpressHeight + 2f); float num3 = num2 + Mathf.Max(8f, empressAssets.EmpressHeight + 4f); float num4 = Mathf.Max(empressAssets.EmpressFloorOffset, 0.18f) + 0.06f; NavMeshHit val2 = default(NavMeshHit); RaycastHit val3 = default(RaycastHit); foreach (Vector2 item in EmpressSpawnProbeOffsets.OrderBy((Vector2 _) => random.Next())) { Vector3 val = anchorSeed + new Vector3(item.x * num, 0f, item.y * num); if (!NavMesh.SamplePosition(val, ref val2, navMeshRadius, -1)) { continue; } val = ((NavMeshHit)(ref val2)).position; if ((Physics.Raycast(val + Vector3.up * num2, Vector3.down, ref val3, num3, EmpressFloorSpawnMask, (QueryTriggerInteraction)1) || Physics.Raycast(val + Vector3.up * num2, Vector3.down, ref val3, num3, -1, (QueryTriggerInteraction)1)) && !(((RaycastHit)(ref val3)).normal.y < 0.45f)) { Vector3 val4 = ((RaycastHit)(ref val3)).point + Vector3.up * num4; Vector3 val5 = val4 + Vector3.up * 0.05f; Vector3 val6 = val4 + Vector3.up * Mathf.Max(empressAssets.EmpressHeight * 0.9f, 0.35f); if (EmpressBlockedSpawnMask == 0 || !Physics.CheckCapsule(val5, val6, Mathf.Max(empressAssets.EmpressRadius * 0.55f, 0.12f), EmpressBlockedSpawnMask, (QueryTriggerInteraction)1)) { position = val4; yaw = (float)random.NextDouble() * 360f; return true; } } } return false; } private PlayerAvatar EmpressResolvePickupPlayer(int requesterPhotonViewId, Player sender) { if (!PhotonNetwork.InRoom || sender == null) { if (requesterPhotonViewId > 0) { PlayerAvatar val = EmpressCoinAccess.EmpressFindPlayerByPhotonViewId(requesterPhotonViewId); if ((Object)(object)val != (Object)null) { return val; } } return EmpressCoinAccess.EmpressFindLocalPlayer(); } PlayerAvatar val2 = EmpressCoinAccess.EmpressFindPlayerByPhotonViewId(requesterPhotonViewId); if ((Object)(object)val2 == (Object)null) { return null; } PhotonView val3 = (((Object)(object)val2.photonView != (Object)null) ? val2.photonView : ((Component)val2).GetComponent()); if ((Object)(object)val3 == (Object)null || val3.Owner == null || val3.Owner.ActorNumber != sender.ActorNumber) { return null; } return val2; } private void EmpressRebuildSceneCoins() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) EmpressDestroySceneCoins(); if (!empressCurrentSettings.EmpressEnabled || empressAssets == null || !empressAssets.EmpressHasPrefab) { return; } EmpressEnsureSceneRoot(); foreach (EmpressCoinSpawnPoint empressSpawnPoint in empressSpawnPoints) { if (!empressPickedCoins.Contains(empressSpawnPoint.EmpressCoinId)) { GameObject val = empressAssets.EmpressInstantiateCoin(null, empressSpawnPoint.EmpressPosition, Quaternion.Euler(0f, empressSpawnPoint.EmpressYaw, 0f)); if (!((Object)(object)val == (Object)null)) { val.transform.SetParent((Transform)null, true); SceneManager.MoveGameObjectToScene(val, EmpressCoinAccess.EmpressActiveScene()); Vector3 empressPickupPosition = EmpressLiftCoinAboveFloor(val); val.transform.SetParent(empressSceneRoot.transform, true); EmpressCoinSceneCoin empressCoinSceneCoin = val.GetComponent() ?? val.AddComponent(); empressCoinSceneCoin.EmpressCoinId = empressSpawnPoint.EmpressCoinId; empressCoinSceneCoin.EmpressPickupPosition = empressPickupPosition; empressSceneCoins[empressSpawnPoint.EmpressCoinId] = empressCoinSceneCoin; } } } } private void EmpressEnsureSceneRoot() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)empressSceneRoot != (Object)null)) { empressSceneRoot = new GameObject("EmpressCoin.SceneRoot"); ((Object)empressSceneRoot).hideFlags = (HideFlags)1; SceneManager.MoveGameObjectToScene(empressSceneRoot, EmpressCoinAccess.EmpressActiveScene()); } } private void EmpressScanForLocalPickups() { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (empressSceneCoins.Count == 0 || !empressCurrentSettings.EmpressEnabled || (Object)(object)empressRelay == (Object)null) { return; } PlayerAvatar val = EmpressCoinAccess.EmpressFindLocalPlayer(); if ((Object)(object)val == (Object)null || EmpressCoinAccess.EmpressPlayerDisabled(val)) { return; } PhotonView val2 = (((Object)(object)val.photonView != (Object)null) ? val.photonView : ((Component)val).GetComponent()); int requesterPhotonViewId = (((Object)(object)val2 != (Object)null) ? val2.ViewID : 0); EmpressCoinSceneCoin empressCoinSceneCoin = null; float num = float.MaxValue; foreach (EmpressCoinSceneCoin value in empressSceneCoins.Values) { if (!((Object)(object)value == (Object)null) && !(Time.unscaledTime < value.EmpressNextRequestTime)) { float num2 = Vector3.Distance(((Component)val).transform.position, value.EmpressPickupPosition); if (num2 <= empressCurrentSettings.EmpressPickupRange && num2 < num) { empressCoinSceneCoin = value; num = num2; } } } if (!((Object)(object)empressCoinSceneCoin == (Object)null)) { empressCoinSceneCoin.EmpressNextRequestTime = Time.unscaledTime + 0.75f; empressPlugin.EmpressDebug("pickup requested for coin " + empressCoinSceneCoin.EmpressCoinId + " at distance " + num.ToString("0.##", CultureInfo.InvariantCulture) + "."); empressRelay.EmpressRequestPickup(empressCoinSceneCoin.EmpressCoinId, requesterPhotonViewId); } } private bool EmpressRemoveCoin(int coinId) { if (!empressSceneCoins.TryGetValue(coinId, out var value)) { return false; } empressSceneCoins.Remove(coinId); if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)((Component)value).gameObject); } return true; } private void EmpressClearSceneState() { EmpressDestroySceneCoins(); empressSpawnLookup.Clear(); empressSpawnPoints.Clear(); empressPickedCoins.Clear(); empressSessionToken = string.Empty; empressSceneName = string.Empty; empressAppliedSceneHandle = -1; empressCurrentSettings = default(EmpressCoinAuthoritySettings); } private void EmpressDestroySceneCoins() { foreach (EmpressCoinSceneCoin value in empressSceneCoins.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)((Component)value).gameObject); } } empressSceneCoins.Clear(); if ((Object)(object)empressSceneRoot != (Object)null) { Object.Destroy((Object)(object)empressSceneRoot); empressSceneRoot = null; } } private Vector3 EmpressLiftCoinAboveFloor(GameObject coinObject) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //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) //IL_005d: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)coinObject == (Object)null || empressAssets == null) { return Vector3.zero; } Vector3 position = coinObject.transform.position; float num = Mathf.Max(2f, empressAssets.EmpressHeight + 1.5f); float num2 = num + Mathf.Max(6f, empressAssets.EmpressHeight + 3f); RaycastHit val = default(RaycastHit); if (!Physics.Raycast(position + Vector3.up * num, Vector3.down, ref val, num2, -1, (QueryTriggerInteraction)1)) { return position; } if (!EmpressTryGetCoinBounds(coinObject, out var bounds)) { coinObject.transform.position = ((RaycastHit)(ref val)).point + Vector3.up * (Mathf.Max(empressAssets.EmpressFloorOffset, 0.14f) + 0.05f); return coinObject.transform.position; } float num3 = ((RaycastHit)(ref val)).point.y + 0.05f - ((Bounds)(ref bounds)).min.y; if (num3 > 0f) { Transform transform = coinObject.transform; transform.position += Vector3.up * num3; } return coinObject.transform.position; } private static bool EmpressTryGetCoinBounds(GameObject coinObject, out Bounds bounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); if ((Object)(object)coinObject == (Object)null) { return false; } bool flag = false; Renderer[] componentsInChildren = coinObject.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } Collider[] componentsInChildren2 = coinObject.GetComponentsInChildren(true); foreach (Collider val2 in componentsInChildren2) { if (!flag) { bounds = val2.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val2.bounds); } } return flag; } } }