Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of IndustrialGoldSafe v1.0.1
plugins/IndustrialGoldSafe/IndustrialGoldSafe.dll
Decompiled 4 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using IndustrialGoldSafe.Core; using LethalLib.Modules; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.LowLevel; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("IndustrialGoldSafe")] [assembly: AssemblyDescription("Host-authoritative indoor gold safes with a shared timing challenge.")] [assembly: AssemblyCompany("Serenta")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace IndustrialGoldSafe.Runtime { internal static class DecoderItems { private sealed class Claim { internal NetworkObject Item; internal NetworkManager Manager; internal ulong Installer; } private sealed class ObservedMount { internal ulong LevelNonce; internal ulong ItemId; internal NetworkObject Item; } private static AssetBundle bundle; private static GameObject mountedArt; private static Material material; internal static GameObject Prefab; internal static Item Definition; private static readonly Dictionary<ulong, Claim> claims = new Dictionary<ulong, Claim>(); private static readonly Dictionary<ulong, NetworkObject> consumedLocally = new Dictionary<ulong, NetworkObject>(); private static readonly Dictionary<ulong, ObservedMount> observedMounts = new Dictionary<ulong, ObservedMount>(); internal static void Initialize(string pluginDirectory) { //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010a: 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) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Expected O, but got Unknown //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Prefab != (Object)null) { return; } string text = Path.Combine(pluginDirectory, "industrialgolddecoder_assets"); bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)bundle == (Object)null) { throw new FileNotFoundException("Missing industrialgolddecoder_assets next to IndustrialGoldSafe.dll.", text); } mountedArt = bundle.LoadAsset<GameObject>("assets/decodergenerated/industrialdecoderart.prefab"); GameObject val = bundle.LoadAsset<GameObject>("assets/decodergenerated/industrialdecoderheldart.prefab"); if ((Object)(object)mountedArt == (Object)null || (Object)(object)val == (Object)null) { throw new InvalidDataException("Decoder art prefabs are missing from the asset bundle."); } material = BuildMaterial(); Prefab = NetworkPrefabs.CreateNetworkPrefab("IndustrialGoldSafe.NetworkDecoder.v1"); int num = LayerMask.NameToLayer("Props"); Prefab.layer = ((num >= 0) ? num : 6); Prefab.tag = "PhysicsProp"; GameObject val2 = Object.Instantiate<GameObject>(val, Prefab.transform); ((Object)val2).name = "DecoderArt"; val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one; ApplyMaterial(val2); BoxCollider val3 = Prefab.AddComponent<BoxCollider>(); Bounds val4 = ModelBounds(val2, Prefab.transform); val3.center = ((Bounds)(ref val4)).center; val3.size = ((Bounds)(ref val4)).size + new Vector3(0.02f, 0.02f, 0.02f); Rigidbody val5 = Prefab.AddComponent<Rigidbody>(); val5.isKinematic = true; val5.useGravity = false; Item val6 = ScriptableObject.CreateInstance<Item>(); ((Object)val6).name = "IndustrialGoldSafe.SafeDecoder.Item.v1"; val6.itemId = 1768616049; val6.itemName = "Safe decoder"; val6.spawnPositionTypes = new List<ItemGroup>(); val6.twoHanded = false; val6.twoHandedAnimation = false; val6.canBeGrabbedBeforeGameStart = true; val6.disallowUtilitySlot = true; val6.weight = 1.0380952f; val6.isConductiveMetal = true; val6.isScrap = false; val6.itemSpawnsOnGround = true; val6.requiresBattery = false; val6.saveItemVariable = false; val6.spawnPrefab = Prefab; val6.allowDroppingAheadOfPlayer = true; val6.toolTips = new string[1] { "Install on safe : [E]" }; val6.grabAnim = (val6.useAnim = (val6.pocketAnim = (val6.throwAnim = ""))); val6.meshVariants = Array.Empty<Mesh>(); val6.materialVariants = Array.Empty<Material>(); val6.clinkAudios = Array.Empty<AudioClip>(); val6.positionOffset = new Vector3(0.02f, 0.03f, -0.05f); val6.rotationOffset = new Vector3(0f, 0f, 0f); val6.verticalOffset = Mathf.Max(0.02f, 0f - ((Bounds)(ref val4)).min.y); val6.itemIcon = bundle.LoadAsset<Sprite>("assets/decodergenerated/decoder_icon.png"); if ((Object)(object)val6.itemIcon == (Object)null) { Texture2D val7 = bundle.LoadAsset<Texture2D>("assets/decodergenerated/decoder_icon.png"); if ((Object)(object)val7 != (Object)null) { val6.itemIcon = Sprite.Create(val7, new Rect(0f, 0f, (float)((Texture)val7).width, (float)((Texture)val7).height), new Vector2(0.5f, 0.5f), 100f); } } if ((Object)(object)val6.itemIcon == (Object)null) { throw new InvalidDataException("Decoder inventory icon is missing."); } Definition = val6; ScanNodeProperties val8 = SafeScanning.Add(Prefab, ((Bounds)(ref val4)).center, ((Bounds)(ref val4)).size + new Vector3(0.02f, 0.02f, 0.02f), "Safe decoder", "Single-use safe decoder"); PhysicsProp val9 = Prefab.AddComponent<PhysicsProp>(); ((GrabbableObject)val9).itemProperties = val6; ((GrabbableObject)val9).grabbable = true; ((GrabbableObject)val9).grabbableToEnemies = false; ((GrabbableObject)val9).isInFactory = true; ((GrabbableObject)val9).insertedBattery = new Battery(false, 1f); ((GrabbableObject)val9).propBody = val5; ((GrabbableObject)val9).propColliders = (Collider[])(object)new Collider[2] { (Collider)val3, (Collider)((Component)val8).GetComponent<BoxCollider>() }; ((GrabbableObject)val9).mainObjectRenderer = val2.GetComponentInChildren<MeshRenderer>(true); NetworkObject component = Prefab.GetComponent<NetworkObject>(); component.DontDestroyWithOwner = true; component.AutoObjectParentSync = false; Items.RegisterItem(val6); SafePlugin.Log.LogInfo((object)"Safe decoder registered as a one-handed, battery-free 4 lb utility item with native scanning; only safe drops create it."); } internal static bool IsHeldDecoder(PlayerControllerB player, out ulong id) { id = ulong.MaxValue; if ((Object)(object)player == (Object)null || (Object)(object)Definition == (Object)null || (Object)(object)player.currentlyHeldObjectServer == (Object)null) { return false; } GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer; NetworkObject networkObject = ((NetworkBehaviour)currentlyHeldObjectServer).NetworkObject; int currentItemSlot = player.currentItemSlot; if (((object)currentlyHeldObjectServer).GetType() != typeof(PhysicsProp) || (Object)(object)currentlyHeldObjectServer.itemProperties != (Object)(object)Definition || !currentlyHeldObjectServer.isHeld || currentlyHeldObjectServer.isPocketed || (Object)(object)currentlyHeldObjectServer.playerHeldBy != (Object)(object)player || currentlyHeldObjectServer.deactivated || !currentlyHeldObjectServer.grabbable || (Object)(object)networkObject == (Object)null || !networkObject.IsSpawned || player.ItemSlots == null || currentItemSlot < 0 || currentItemSlot >= player.ItemSlots.Length || (Object)(object)player.ItemSlots[currentItemSlot] != (Object)(object)currentlyHeldObjectServer) { return false; } id = networkObject.NetworkObjectId; return true; } internal static bool ValidateAndMount(ulong sender, ulong safeId, ulong itemId) { //IL_00ca: 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) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsServer || !singleton.IsListening || singleton.ShutdownInProgress || singleton.SpawnManager == null || !singleton.ConnectedClients.ContainsKey(sender) || !SafeView.Find(safeId, out var result) || !singleton.SpawnManager.SpawnedObjects.TryGetValue(itemId, out var value) || (Object)(object)value == (Object)null || !value.IsSpawned || (Object)(object)value.NetworkManager != (Object)(object)singleton || claims.ContainsKey(itemId)) { return false; } PlayerControllerB val = FindPlayer(sender); if ((Object)(object)val == (Object)null || !val.isPlayerControlled || val.isPlayerDead || !val.isInsideFactory || ((NetworkBehaviour)val).OwnerClientId != sender || value.OwnerClientId != sender || Vector3.Distance(((Component)val).transform.position, ((Component)result).transform.position) > SafePlugin.Settings.Distance.Value || !IsHeldDecoder(val, out var id) || id != itemId || (Object)(object)((NetworkBehaviour)val.currentlyHeldObjectServer).NetworkObject != (Object)(object)value) { return false; } GrabbableObject currentlyHeldObjectServer = val.currentlyHeldObjectServer; claims.Add(itemId, new Claim { Item = value, Manager = singleton, Installer = sender }); currentlyHeldObjectServer.grabbable = false; currentlyHeldObjectServer.grabbableToEnemies = false; currentlyHeldObjectServer.deactivated = true; currentlyHeldObjectServer.isBeingUsed = false; currentlyHeldObjectServer.EnableItemMeshes(false); SafeScanning.Hide(currentlyHeldObjectServer); SafePlugin.Log.LogInfo((object)$"Decoder #{itemId} installed on safe #{safeId} by client {sender}."); return true; } internal static void ObserveMount(SafeSnapshot state) { //IL_003f: 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) if (state == null || state.Mode != SafeMode.Decoding || state.DecoderObjectId == ulong.MaxValue) { return; } NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsListening || singleton.ShutdownInProgress || singleton.SpawnManager == null) { return; } NetworkTime serverTime = singleton.ServerTime; if (((NetworkTime)(ref serverTime)).Time > state.DecodeDeadline) { return; } NetworkObject value2; if (observedMounts.TryGetValue(state.SafeId, out var value) && value.LevelNonce == state.LevelNonce) { value2 = value.Item; if (value.ItemId != state.DecoderObjectId || (Object)(object)value2 == (Object)null || !value2.IsSpawned) { return; } } else { if (!singleton.SpawnManager.SpawnedObjects.TryGetValue(state.DecoderObjectId, out value2) || (Object)(object)value2 == (Object)null) { return; } PhysicsProp component = ((Component)value2).GetComponent<PhysicsProp>(); if ((Object)(object)component == (Object)null || (Object)(object)((GrabbableObject)component).itemProperties != (Object)(object)Definition) { return; } observedMounts[state.SafeId] = new ObservedMount { LevelNonce = state.LevelNonce, ItemId = state.DecoderObjectId, Item = value2 }; } PhysicsProp component2 = ((Component)value2).GetComponent<PhysicsProp>(); if ((Object)(object)component2 == (Object)null || (Object)(object)((GrabbableObject)component2).itemProperties != (Object)(object)Definition) { return; } ((GrabbableObject)component2).grabbable = false; ((GrabbableObject)component2).grabbableToEnemies = false; ((GrabbableObject)component2).deactivated = true; ((GrabbableObject)component2).EnableItemMeshes(false); SafeScanning.Hide((GrabbableObject)(object)component2); if (state.DecoderInstallerClientId != singleton.LocalClientId || (consumedLocally.TryGetValue(state.DecoderObjectId, out var value3) && value3 == value2)) { return; } PlayerControllerB val = FindPlayer(state.DecoderInstallerClientId); if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).IsOwner || val.ItemSlots == null) { return; } for (int i = 0; i < val.ItemSlots.Length; i++) { if ((object)val.ItemSlots[i] != component2) { continue; } bool flag = val.currentItemSlot == i; if (!flag || !val.isHoldingObject || (object)val.currentlyHeldObjectServer == component2) { bool num = flag && val.isHoldingObject; float carryWeight = val.carryWeight; val.DestroyItemInSlotAndSync(i); if (!num) { val.carryWeight = Mathf.Clamp(carryWeight - Mathf.Max(0f, Definition.weight - 1f), 1f, 10f); } StartOfRound instance = StartOfRound.Instance; if (instance != null) { instance.SendChangedWeightEvent(); } consumedLocally[state.DecoderObjectId] = value2; } break; } } internal static void Tick() { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsServer || !singleton.IsListening || singleton.ShutdownInProgress) { return; } foreach (KeyValuePair<ulong, Claim> item2 in new List<KeyValuePair<ulong, Claim>>(claims)) { Claim value = item2.Value; NetworkObject item = value.Item; if (value.Manager != singleton) { claims.Remove(item2.Key); continue; } if ((Object)(object)item == (Object)null || !item.IsSpawned) { if (SafeNetworking.ReleaseConsumedDecoder(item2.Key)) { claims.Remove(item2.Key); } continue; } GrabbableObject component = ((Component)item).GetComponent<GrabbableObject>(); bool flag = !singleton.ConnectedClients.ContainsKey(value.Installer); bool flag2 = (Object)(object)component != (Object)null && !component.isHeld && !component.heldByPlayerOnServer && !HasInventoryReference(component); if (!flag && !flag2) { continue; } if (flag) { RemoveDisconnectedReferences(component); } try { item.Despawn(true); if (SafeNetworking.ReleaseConsumedDecoder(item2.Key)) { claims.Remove(item2.Key); } } catch (Exception ex) { SafePlugin.Log.LogWarning((object)("Decoder consumption cleanup deferred: " + ex.Message)); } } } internal static void Spawn(Transform safe, bool testPlacement = false) { //IL_0068: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; RoundManager instance = RoundManager.Instance; if ((Object)(object)singleton == (Object)null || !singleton.IsServer || (Object)(object)instance == (Object)null || (Object)(object)Prefab == (Object)null || (Object)(object)safe == (Object)null) { return; } GameObject val = null; try { Vector3 val2 = safe.TransformPoint(testPlacement ? new Vector3(0f, 0.5f, 1.25f) : new Vector3(0.72f, 0.5f, 1.05f)); RaycastHit val3 = default(RaycastHit); if ((Object)(object)StartOfRound.Instance != (Object)null && Physics.Raycast(val2 + Vector3.up, Vector3.down, ref val3, 3f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1)) { val2.y = ((RaycastHit)(ref val3)).point.y + 0.5f; } val = Object.Instantiate<GameObject>(Prefab, val2, Quaternion.identity, instance.spawnedScrapContainer); PhysicsProp component = val.GetComponent<PhysicsProp>(); ((GrabbableObject)component).isInFactory = true; ((GrabbableObject)component).isInElevator = (((GrabbableObject)component).isInShipRoom = false); ((GrabbableObject)component).fallTime = 0f; val.SetActive(true); NetworkObject component2 = val.GetComponent<NetworkObject>(); component2.Spawn(false); SafePlugin.Log.LogInfo((object)$"Extra safe decoder #{component2.NetworkObjectId} spawned independently of the gold reward batch."); } catch (Exception ex) { if ((Object)(object)val != (Object)null) { NetworkObject component3 = val.GetComponent<NetworkObject>(); if ((Object)(object)component3 == (Object)null || !component3.IsSpawned) { Object.Destroy((Object)(object)val); } } SafePlugin.Log.LogError((object)("Extra safe decoder spawn failed: " + ex)); } } internal static GameObject CreateMountedArt(Transform hinge) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) if ((Object)(object)mountedArt == (Object)null || (Object)(object)hinge == (Object)null) { return null; } GameObject val = Object.Instantiate<GameObject>(mountedArt, hinge); ((Object)val).name = "MountedDecoder"; val.transform.localPosition = -hinge.localPosition; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; ApplyMaterial(val); Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } return val; } internal static void ClearWorld() { claims.Clear(); consumedLocally.Clear(); observedMounts.Clear(); } internal static void Shutdown() { ClearWorld(); if ((Object)(object)bundle != (Object)null) { bundle.Unload(false); } bundle = null; } private static PlayerControllerB FindPlayer(ulong client) { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val != (Object)null && val.actualClientId == client && ((NetworkBehaviour)val).OwnerClientId == client) { return val; } PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array != null) { PlayerControllerB[] array2 = array; foreach (PlayerControllerB val2 in array2) { if ((Object)(object)val2 != (Object)null && val2.isPlayerControlled && val2.actualClientId == client && ((NetworkBehaviour)val2).OwnerClientId == client) { return val2; } } } return null; } private static bool HasInventoryReference(GrabbableObject prop) { PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return false; } PlayerControllerB[] array2 = array; foreach (PlayerControllerB val in array2) { if ((Object)(object)val == (Object)null) { continue; } if (val.currentlyHeldObjectServer == prop || val.ItemOnlySlot == prop) { return true; } if (val.ItemSlots == null) { continue; } GrabbableObject[] itemSlots = val.ItemSlots; for (int j = 0; j < itemSlots.Length; j++) { if (itemSlots[j] == prop) { return true; } } } return false; } private static void RemoveDisconnectedReferences(GrabbableObject prop) { if ((Object)(object)prop == (Object)null) { return; } PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return; } PlayerControllerB[] array2 = array; foreach (PlayerControllerB val in array2) { if ((Object)(object)val == (Object)null) { continue; } bool flag = false; if (val.ItemSlots != null) { for (int j = 0; j < val.ItemSlots.Length; j++) { if (val.ItemSlots[j] == prop) { val.ItemSlots[j] = null; flag = true; } } } if (val.ItemOnlySlot == prop) { val.ItemOnlySlot = null; flag = true; } if (val.currentlyHeldObjectServer == prop) { val.currentlyHeldObjectServer = null; val.isHoldingObject = (val.twoHanded = (val.twoHandedAnimation = (val.activatingItem = false))); } if (flag) { val.carryWeight = Mathf.Clamp(val.carryWeight - Mathf.Max(0f, Definition.weight - 1f), 1f, 10f); } } } private static Material BuildMaterial() { //IL_0082: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_017b: Expected O, but got Unknown Shader val = Shader.Find("HDRP/Lit"); if ((Object)(object)val == (Object)null) { Material[] array = Resources.FindObjectsOfTypeAll<Material>(); foreach (Material val2 in array) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2.shader != (Object)null && ((Object)val2.shader).name == "HDRP/Lit") { val = val2.shader; break; } } } if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("Game HDRP/Lit shader was not found for the decoder."); } Material val3 = new Material(val) { name = "IndustrialGoldSafe.Decoder.HDRP" }; Texture2D val4 = bundle.LoadAsset<Texture2D>("assets/decodersource/decoder_basecolor_512.png"); Texture2D val5 = bundle.LoadAsset<Texture2D>("assets/decodergenerated/decoder_maskmap_512.png"); if ((Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null) { throw new InvalidDataException("Decoder base-color or HDRP mask texture is missing."); } val3.SetTexture("_BaseColorMap", (Texture)(object)val4); val3.SetTexture("_MaskMap", (Texture)(object)val5); val3.SetColor("_BaseColor", Color.white); val3.SetFloat("_Metallic", 1f); val3.SetFloat("_Smoothness", 1f); val3.SetFloat("_SmoothnessRemapMin", 0f); val3.SetFloat("_SmoothnessRemapMax", 1f); val3.SetFloat("_SurfaceType", 0f); val3.SetFloat("_MaterialID", 1f); val3.SetFloat("_NormalMapSpace", 0f); if (!HDMaterial.ValidateMaterial(val3)) { throw new InvalidOperationException("HDRP could not validate the decoder material."); } return val3; } private static void ApplyMaterial(GameObject model) { Renderer[] componentsInChildren = model.GetComponentsInChildren<Renderer>(true); foreach (Renderer obj in componentsInChildren) { obj.sharedMaterial = material; obj.renderingLayerMask = 1u; obj.shadowCastingMode = (ShadowCastingMode)1; obj.receiveShadows = true; obj.lightProbeUsage = (LightProbeUsage)1; obj.reflectionProbeUsage = (ReflectionProbeUsage)1; } } private static Bounds ModelBounds(GameObject model, Transform root) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00aa: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) Bounds result = default(Bounds); ((Bounds)(ref result))..ctor(Vector3.zero, Vector3.one * 0.01f); bool flag = false; MeshFilter[] componentsInChildren = model.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { if ((Object)(object)val.sharedMesh == (Object)null) { continue; } Bounds bounds = val.sharedMesh.bounds; for (int j = 0; j < 8; j++) { Vector3 val2 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1)))); val2 = root.InverseTransformPoint(((Component)val).transform.TransformPoint(val2)); if (!flag) { ((Bounds)(ref result))..ctor(val2, Vector3.zero); flag = true; } else { ((Bounds)(ref result)).Encapsulate(val2); } } } return result; } } internal static class GoldRewards { internal static int? ReadCurrentValue(ulong id) { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.SpawnManager != null && singleton.SpawnManager.SpawnedObjects.TryGetValue(id, out var value) && (Object)(object)value != (Object)null) { GrabbableObject component = ((Component)value).GetComponent<GrabbableObject>(); if ((Object)(object)component != (Object)null) { return component.scrapValue; } } return null; } internal static void ApplyValue(ulong id, int value) { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.SpawnManager != null && singleton.SpawnManager.SpawnedObjects.TryGetValue(id, out var value2) && (Object)(object)value2 != (Object)null) { GrabbableObject component = ((Component)value2).GetComponent<GrabbableObject>(); if (component != null) { component.SetScrapValue(value); } } } internal static void AddStatistics(int delta) { if ((Object)(object)RoundManager.Instance != (Object)null) { RoundManager instance = RoundManager.Instance; instance.totalScrapValueInLevel += (float)delta; } } internal static void Spawn(Transform safe, SafeSettings settings, SafeRewardPlan plan) { //IL_012b: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; RoundManager instance = RoundManager.Instance; if ((Object)(object)singleton == (Object)null || !singleton.IsServer || (Object)(object)instance == (Object)null) { return; } if (plan == null) { throw new ArgumentNullException("plan"); } HashSet<string> exclude = new HashSet<string>(from s in (settings.ExcludedGold.Value ?? "").Split(',') select s.Trim(), StringComparer.OrdinalIgnoreCase); ItemData[] array = (GoldScrapPlugin.allGoldGrabbableObjects ?? Array.Empty<ItemData>()).Where((ItemData i) => (Object)(object)i != (Object)null && i.isScrap && !i.isStoreItem && (Object)(object)i.itemProperties != (Object)null && (Object)(object)i.itemProperties.spawnPrefab != (Object)null && !exclude.Contains(i.folderName)).ToArray(); if (array.Length == 0) { SafePlugin.Log.LogError((object)"Safe opened but gold reward pool is empty. Check ExcludedGoldIDs and GoldScrapLite."); return; } Random random = plan.CreateRewardRandom(); int count = plan.Count; int num = 0; float num2 = 0f; Vector3 val3 = default(Vector3); RaycastHit val5 = default(RaycastHit); for (int num3 = 0; num3 < count; num3++) { GameObject val = null; try { ItemData val2 = array[random.Next(array.Length)]; Item itemProperties = val2.itemProperties; ((Vector3)(ref val3))..ctor((float)(num3 % 3 - 1) * 0.5f, 0.5f, 1.2f + (float)(num3 / 3) * 0.5f); Vector3 val4 = safe.TransformPoint(val3); if (Physics.Raycast(val4 + Vector3.up, Vector3.down, ref val5, 3f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1)) { val4.y = ((RaycastHit)(ref val5)).point.y + 0.5f; } val = Object.Instantiate<GameObject>(itemProperties.spawnPrefab, val4, Quaternion.Euler(itemProperties.restingRotation), instance.spawnedScrapContainer); GrabbableObject component = val.GetComponent<GrabbableObject>(); NetworkObject component2 = val.GetComponent<NetworkObject>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { throw new InvalidOperationException("Gold prefab lacks GrabbableObject / NetworkObject: " + val2.folderName); } component.isInFactory = true; component.isInShipRoom = false; component.isInElevator = false; component.fallTime = 0f; int num4 = Math.Max(0, Math.Min(itemProperties.minValue, itemProperties.maxValue)); int num5 = Math.Max(num4, Math.Max(itemProperties.minValue, itemProperties.maxValue)); double num6 = ((num5 == num4) ? num4 : random.Next(num4, num5)); int num7 = (int)Math.Min(2147483647.0, Math.Max(0.0, num6 * (double)instance.scrapValueMultiplier * (double)settings.ValueMultiplier.Value)); component.SetScrapValue(num7); component2.Spawn(false); SafeNetworking.RecordReward(component2.NetworkObjectId, num7); SafeNetworking.RecordStatisticsAdded(component2.NetworkObjectId, num7); num++; num2 += (float)num7; SafePlugin.Log.LogInfo((object)$"Safe reward #{component2.NetworkObjectId}: {val2.folderName}, ${num7}."); } catch (Exception arg) { if ((Object)(object)val != (Object)null) { NetworkObject component3 = val.GetComponent<NetworkObject>(); if ((Object)(object)component3 == (Object)null || !component3.IsSpawned) { Object.Destroy((Object)(object)val); } } SafePlugin.Log.LogError((object)$"Safe reward {num3 + 1}/{count} failed: {arg}"); } } SafePlugin.Log.LogInfo((object)$"Safe rewards delivered: {num}/{count}, pool {array.Length}, total ${num2}."); } } internal enum SafeSound { Start, Press, Step, Fail, Jam, Open, DecoderLoop } internal static class SafeAudio { private const int SampleRate = 24000; internal const float CompletionGapSeconds = 0.15f; private static readonly AudioClip[] Clips = (AudioClip[])(object)new AudioClip[7]; private static readonly List<AudioSource> WorldSources = new List<AudioSource>(); private static readonly List<AudioSource> DecoderLoops = new List<AudioSource>(); private static AudioSource localSource; private static float volume = 0.6f; internal static float Volume { get { return volume; } set { volume = ((float.IsNaN(value) || float.IsInfinity(value)) ? 0.6f : Mathf.Clamp01(value)); } } internal static void Local(SafeSound sound, float level = 1f) { //IL_0022: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown float num = Gain(level); if (!(num <= 0f)) { if ((Object)(object)localSource == (Object)null) { GameObject val = new GameObject("IndustrialGoldSafe.LocalAudio") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); localSource = val.AddComponent<AudioSource>(); Configure(localSource); localSource.spatialBlend = 0f; localSource.bypassReverbZones = true; } localSource.PlayOneShot(GetClip(sound), num); } } internal static void World(SafeSound sound, Vector3 position, float level = 1f) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) WorldDelayed(sound, position, 0f, level); } internal static void WorldCompletion(Vector3 position) { //IL_0001: 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) World(SafeSound.Step, position); WorldDelayed(SafeSound.Open, position, 0.15f); } internal static void WorldDelayed(SafeSound sound, Vector3 position, float delaySeconds, float level = 1f) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown float num = Gain(level); if (num <= 0f) { return; } float num2 = ((float.IsNaN(delaySeconds) || float.IsInfinity(delaySeconds)) ? 0f : Mathf.Clamp(delaySeconds, 0f, 5f)); for (int num3 = WorldSources.Count - 1; num3 >= 0; num3--) { if ((Object)(object)WorldSources[num3] == (Object)null) { WorldSources.RemoveAt(num3); } } if (WorldSources.Count >= 12) { Object.Destroy((Object)(object)((Component)WorldSources[0]).gameObject); WorldSources.RemoveAt(0); } AudioClip clip = GetClip(sound); GameObject val = new GameObject("IndustrialGoldSafe.WorldAudio") { hideFlags = (HideFlags)61 }; val.transform.position = position; AudioSource val2 = val.AddComponent<AudioSource>(); Configure(val2); val2.spatialBlend = 1f; val2.rolloffMode = (AudioRolloffMode)1; val2.minDistance = 1.5f; val2.maxDistance = 16f; val2.spread = 20f; val2.volume = num; val2.clip = clip; WorldSources.Add(val2); if (num2 > 0f) { val2.PlayDelayed(num2); } else { val2.Play(); } Object.Destroy((Object)val, num2 + clip.length + 0.1f); } internal static AudioSource StartDecoderLoop(Transform parent, double elapsedSeconds = 0.0) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)parent == (Object)null) { return null; } for (int num = DecoderLoops.Count - 1; num >= 0; num--) { if ((Object)(object)DecoderLoops[num] == (Object)null) { DecoderLoops.RemoveAt(num); } } if (DecoderLoops.Count >= 12) { StopLoop(DecoderLoops[0]); } GameObject val = new GameObject("IndustrialGoldSafe.DecoderLoop"); val.transform.SetParent(parent, false); AudioSource val2 = val.AddComponent<AudioSource>(); Configure(val2); val2.spatialBlend = 1f; val2.rolloffMode = (AudioRolloffMode)1; val2.minDistance = 1.5f; val2.maxDistance = 16f; val2.spread = 20f; val2.loop = true; val2.clip = GetClip(SafeSound.DecoderLoop); val2.volume = Gain(1f); if (!double.IsNaN(elapsedSeconds) && !double.IsInfinity(elapsedSeconds) && elapsedSeconds > 0.0 && val2.clip.length > 0f) { val2.time = (float)(elapsedSeconds % (double)val2.clip.length); } DecoderLoops.Add(val2); val2.Play(); return val2; } internal static void RefreshDecoderLoop(AudioSource source) { if ((Object)(object)source != (Object)null) { source.volume = Gain(1f); } } internal static void StopLoop(AudioSource source) { if (!((Object)(object)source == (Object)null)) { DecoderLoops.Remove(source); source.Stop(); source.loop = false; Object.Destroy((Object)(object)((Component)source).gameObject); } } private static void Configure(AudioSource source) { source.playOnAwake = false; source.loop = false; source.dopplerLevel = 0f; source.pitch = 1f; source.volume = 1f; source.priority = 128; } private static float Gain(float level) { if (!float.IsNaN(level) && !float.IsInfinity(level)) { return Volume * Mathf.Clamp01(level); } return 0f; } internal static AudioClip GetClip(SafeSound sound) { int num = (int)sound; if (num < 0 || num >= Clips.Length) { throw new ArgumentOutOfRangeException("sound"); } if ((Object)(object)Clips[num] != (Object)null) { return Clips[num]; } double num2; switch (sound) { case SafeSound.Step: case SafeSound.Jam: case SafeSound.Open: case SafeSound.DecoderLoop: { string resource = sound switch { SafeSound.DecoderLoop => "IndustrialGoldSafe.Audio.DecoderLoop.wav", SafeSound.Jam => "IndustrialGoldSafe.Audio.Jam.wav", SafeSound.Step => "IndustrialGoldSafe.Audio.Success.wav", _ => "IndustrialGoldSafe.Audio.Open.wav", }; Clips[num] = LoadRecordedClip(resource, sound); return Clips[num]; } default: num2 = sound switch { SafeSound.Jam => 0.46, SafeSound.Fail => 0.27, SafeSound.Start => 0.22, SafeSound.Step => 0.16, _ => 0.76, }; break; case SafeSound.Press: num2 = 0.075; break; } double num3 = num2; float[] array = new float[(int)Math.Ceiling(num3 * 24000.0)]; uint num4 = (uint)(833049489 + num * 1630357685); double num5 = 0.0; for (int i = 0; i < array.Length; i++) { num4 ^= num4 << 13; num4 ^= num4 >> 17; num4 ^= num4 << 5; double num6 = (double)(num4 & 0xFFFFFF) / 8388607.5 - 1.0; num5 += (num6 - num5) * 0.18; double num7 = (double)i / 24000.0; double num8; switch (sound) { case SafeSound.Start: num8 = Tick(num7, 0.0, 0.09, 520.0, 0.23, num5) + Tick(num7, 0.085, 0.11, 740.0, 0.18, num5); break; case SafeSound.Press: num8 = Tick(num7, 0.0, 0.067, 920.0, 0.21, num5); break; case SafeSound.Step: num8 = Tick(num7, 0.0, 0.07, 1080.0, 0.24, num5) + Tick(num7, 0.055, 0.09, 680.0, 0.13, num5); break; case SafeSound.Fail: num8 = Tick(num7, 0.0, 0.14, 185.0, 0.31, num5) + Tick(num7, 0.065, 0.16, 260.0, 0.17, num5); num8 += Scrape(num7, 0.045, 0.16, 0.11, num5); break; case SafeSound.Jam: num8 = Tick(num7, 0.0, 0.16, 140.0, 0.35, num5) + Tick(num7, 0.075, 0.18, 225.0, 0.26, num5) + Tick(num7, 0.18, 0.23, 170.0, 0.2, num5) + Scrape(num7, 0.08, 0.27, 0.12, num5); break; default: num8 = Tick(num7, 0.0, 0.09, 650.0, 0.24, num5) + Tick(num7, 0.065, 0.12, 420.0, 0.22, num5) + Scrape(num7, 0.13, 0.39, 0.2, num5) + Tick(num7, 0.54, 0.18, 115.0, 0.28, num5); break; } double val = Math.Min(1.0, num7 / 0.0015) * Math.Min(1.0, (num3 - num7) / 0.012); array[i] = (float)Math.Max(-0.55, Math.Min(0.55, num8 * Math.Max(0.0, val))); } AudioClip val2 = AudioClip.Create("IndustrialGoldSafe." + sound, array.Length, 1, 24000, false); ((Object)val2).hideFlags = (HideFlags)61; if (!val2.SetData(array, 0)) { Object.Destroy((Object)(object)val2); throw new InvalidOperationException("Could not upload the generated safe sound."); } Clips[num] = val2; return val2; } private static AudioClip LoadRecordedClip(string resource, SafeSound sound) { using Stream stream = typeof(SafeAudio).Assembly.GetManifestResourceStream(resource); if (stream == null) { throw new InvalidOperationException("Missing embedded safe recording: " + resource); } using BinaryReader binaryReader = new BinaryReader(stream); if (stream.Length < 44 || stream.Length > 1048576 || binaryReader.ReadUInt32() != 1179011410 || binaryReader.ReadUInt32() != stream.Length - 8 || binaryReader.ReadUInt32() != 1163280727) { throw new InvalidDataException("Invalid safe recording RIFF/WAVE header: " + resource); } bool flag = false; byte[] array = null; while (stream.Position + 8 <= stream.Length) { uint num = binaryReader.ReadUInt32(); uint num2 = binaryReader.ReadUInt32(); long num3 = stream.Position + num2; if (num3 > stream.Length || num3 + (num2 & 1) > stream.Length) { throw new InvalidDataException("Truncated safe recording chunk: " + resource); } switch (num) { case 544501094u: if (flag || num2 != 16 || binaryReader.ReadUInt16() != 1 || binaryReader.ReadUInt16() != 1 || binaryReader.ReadUInt32() != 48000 || binaryReader.ReadUInt32() != 96000 || binaryReader.ReadUInt16() != 2 || binaryReader.ReadUInt16() != 16) { throw new InvalidDataException("Safe recordings must be mono 48 kHz PCM16: " + resource); } flag = true; break; case 1635017060u: if (!flag || array != null || num2 == 0 || num2 % 2 != 0) { throw new InvalidDataException("Invalid safe recording sample data: " + resource); } array = binaryReader.ReadBytes((int)num2); if (array.Length != num2) { throw new InvalidDataException("Incomplete safe recording: " + resource); } break; } stream.Position = num3 + (num2 & 1); } if (!flag || array == null || stream.Position != stream.Length) { throw new InvalidDataException("Incomplete safe recording structure: " + resource); } float[] array2 = new float[array.Length / 2]; for (int i = 0; i < array2.Length; i++) { array2[i] = (float)(short)(array[i * 2] | (array[i * 2 + 1] << 8)) / 32768f; } AudioClip val = AudioClip.Create("IndustrialGoldSafe." + sound, array2.Length, 1, 48000, false); ((Object)val).hideFlags = (HideFlags)61; if (!val.SetData(array2, 0)) { Object.Destroy((Object)(object)val); throw new InvalidOperationException("Could not upload the safe recording: " + resource); } return val; } private static double Tick(double time, double start, double duration, double frequency, double gain, double noise) { double num = time - start; if (num < 0.0 || num >= duration) { return 0.0; } double num2 = Math.Min(1.0, num / 0.0015) * Math.Exp((0.0 - num) / (duration * 0.22)) * Math.Min(1.0, (duration - num) / 0.008); double num3 = num * frequency * Math.PI * 2.0; return gain * num2 * (0.56 * noise + 0.3 * Math.Sin(num3) + 0.14 * Math.Sin(num3 * 1.61)); } private static double Scrape(double time, double start, double duration, double gain, double noise) { double num = time - start; if (num < 0.0 || num >= duration) { return 0.0; } double num2 = Math.Sin(num / duration * Math.PI); return gain * noise * num2 * (0.72 + 0.28 * Math.Sin(num * 63.0)); } internal static void Shutdown() { if ((Object)(object)localSource != (Object)null) { Object.Destroy((Object)(object)((Component)localSource).gameObject); } localSource = null; foreach (AudioSource worldSource in WorldSources) { if ((Object)(object)worldSource != (Object)null) { Object.Destroy((Object)(object)((Component)worldSource).gameObject); } } WorldSources.Clear(); foreach (AudioSource item in new List<AudioSource>(DecoderLoops)) { StopLoop(item); } DecoderLoops.Clear(); for (int i = 0; i < Clips.Length; i++) { if ((Object)(object)Clips[i] != (Object)null) { Object.Destroy((Object)(object)Clips[i]); } Clips[i] = null; } } } internal static class SafeDialRaster { internal const int LogicalWidth = 128; internal const int LogicalHeight = 144; internal const int PixelDensity = 2; internal const int Width = 256; internal const int Height = 288; private static readonly Color32[] Pixels; private static readonly Color32[] OutlinedPixels; private static readonly Color32 Outline; private static readonly double[] Radii; private static readonly double[] Phases; private static readonly Color32 Track; private static readonly Color32 Target; private static readonly Color32 Pointer; private static readonly Color32 Timer; private static readonly Color32 Success; private static readonly Color32 Failure; private static readonly string[] Glyphs; private const string Alphabet = "SPACEMILOKDN[]."; static SafeDialRaster() { //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) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) Pixels = (Color32[])(object)new Color32[73728]; OutlinedPixels = (Color32[])(object)new Color32[73728]; Outline = new Color32((byte)0, (byte)0, (byte)0, (byte)245); Radii = new double[73728]; Phases = new double[73728]; Track = new Color32((byte)185, (byte)109, (byte)45, (byte)130); Target = new Color32((byte)246, (byte)158, (byte)58, (byte)230); Pointer = new Color32((byte)232, (byte)228, (byte)205, (byte)230); Timer = new Color32((byte)182, (byte)154, (byte)106, (byte)126); Success = new Color32((byte)156, (byte)193, (byte)113, (byte)230); Failure = new Color32((byte)221, (byte)99, (byte)63, (byte)230); Glyphs = new string[15] { "01111100001000001110000010000111110", "11110100011000111110100001000010000", "01110100011000111111100011000110001", "01111100001000010000100001000001111", "11111100001000011110100001000011111", "10001110111010110101100011000110001", "11111001000010000100001000010011111", "10000100001000010000100001000011111", "01110100011000110001100011000101110", "10001100101010011000101001001010001", "11110100011000110001100011000111110", "10001110011100110101100111001110001", "01110010000100001000010000100001110", "01110000100001000010000100001001110", "00000000000000000000000000010000100" }; for (int i = 0; i < 288; i++) { for (int j = 0; j < 256; j++) { int num = i * 256 + j; double num2 = ((double)j + 0.5) / 2.0 - 64.0; double num3 = ((double)i + 0.5) / 2.0 - 60.0; Radii[num] = Math.Sqrt(num2 * num2 + num3 * num3); Phases[num] = QteMath.WrapPhase(Math.Atan2(num2, 0.0 - num3) / (Math.PI * 2.0)); } } } internal static Texture2D CreateTexture() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0024: 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) //IL_0034: Expected O, but got Unknown return new Texture2D(256, 288, (TextureFormat)4, false, true) { name = "IndustrialGoldSafe.TransparentDial", filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; } internal static void Paint(Texture2D texture, SafeSnapshot state, double serverTime, bool pending) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) double num = QteMath.Pointer(serverTime, state) * Math.PI * 2.0; double num2 = 64.0 + 45.0 * Math.Sin(num); double num3 = 60.0 - 45.0 * Math.Cos(num); bool flag = serverTime < state.StepStartTime; string text = ((state.Mode == SafeMode.Open) ? "OPEN" : ((state.Mode == SafeMode.Jammed) ? "LOCKED" : ((state.Mode == SafeMode.Closed) ? "MISS" : ((flag || pending) ? "..." : "[SPACE]")))); Color32 val = ((state.Mode == SafeMode.Open) ? Success : ((state.Mode == SafeMode.Jammed || state.Mode == SafeMode.Closed) ? Failure : Pointer)); double num4 = (double)(128 - (text.Length * 6 - 1)) / 2.0; double num5 = 57.0; double num6 = Math.Max(0.001, state.Deadline - state.StepStartTime); double num7 = (flag ? 1.0 : Math.Max(0.0, Math.Min(1.0, (state.Deadline - serverTime) / num6))); int num8 = Math.Max(0, Math.Min(30, state.Step)); double num9 = ((num8 > 14) ? 1 : 3); double num10 = Math.Min(5.0, (100.0 - (double)Math.Max(0, num8 - 1) * num9) / (double)Math.Max(1, num8)); double num11 = (double)num8 * num10 + (double)Math.Max(0, num8 - 1) * num9; double num12 = (128.0 - num11) / 2.0; for (int i = 0; i < 288; i++) { for (int j = 0; j < 256; j++) { int num13 = i * 256 + j; double num14 = ((double)j + 0.5) / 2.0; double num15 = ((double)i + 0.5) / 2.0; double num16 = Radii[num13]; double num17 = Phases[num13]; Color32 val2 = default(Color32); if (Math.Abs(num16 - 45.0) < 0.6) { val2 = Track; } if (!pending && Math.Abs(num16 - 45.0) < 2.1 && QteMath.CircleDistance(num17, state.TargetCenter) <= state.TargetWidth / 2.0) { val2 = Target; } if (Math.Abs(num16 - 53.0) < 0.5 && num17 < num7) { val2 = Timer; } if (Math.Abs(num14 - num2) < 1.65 && Math.Abs(num15 - num3) < 1.65) { val2 = Pointer; } int num18 = (int)Math.Floor((double)j / 2.0 - num4); int num19 = i / 2 - (int)num5; int num20 = ((num18 >= 0) ? (num18 / 6) : (-1)); int num21 = num18 % 6; if (num20 >= 0 && num20 < text.Length && num21 >= 0 && num21 < 5 && num19 >= 0 && num19 < 7) { int num22 = "SPACEMILOKDN[].".IndexOf(text[num20]); if (num22 >= 0 && Glyphs[num22][num19 * 5 + num21] == '1') { val2 = val; } } if (num8 > 0 && num15 >= 125.0 && num15 < 127.0) { double num23 = (double)j / 2.0 - num12; int num24 = ((num23 >= 0.0) ? ((int)Math.Floor(num23 / (num10 + num9))) : (-1)); if (num24 >= 0 && num24 < num8 && num23 % (num10 + num9) < num10) { val2 = Target; } } Pixels[(287 - i) * 256 + j] = val2; } } AddOutline(); texture.SetPixels32(OutlinedPixels); texture.Apply(false, false); } private static bool HasMark(int x, int y) { if (x >= 0 && x < 256 && y >= 0 && y < 288) { return Pixels[y * 256 + x].a != 0; } return false; } private static void AddOutline() { //IL_001b: 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_0021: 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_0075: Unknown result type (might be due to invalid IL or missing references) //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) for (int i = 0; i < 288; i++) { for (int j = 0; j < 256; j++) { int num = i * 256 + j; Color32 val = Pixels[num]; if (val.a == 0) { bool flag = false; for (int k = -1; k <= 1; k++) { if (flag) { break; } for (int l = -1; l <= 1; l++) { if (HasMark(j + l, i + k)) { flag = true; break; } } } if (flag) { val = Outline; } } OutlinedPixels[num] = val; } } } } public static class SafeNetworking { private const string HelloName = "Serenta.IndustrialGoldSafe.Hello.4"; private const string CommandName = "Serenta.IndustrialGoldSafe.Command.4"; private const string EventName = "Serenta.IndustrialGoldSafe.Event.4"; private const byte Protocol = 4; private const long MaximumStatisticsTotal = 8796093018112L; private static readonly ManualLogSource Log = Logger.CreateLogSource("IndustrialGoldSafe.Network"); private static SafeNetworkOptions options = new SafeNetworkOptions(); private static Func<ulong, int?> currentRewardValue; private static Func<ulong, ulong, ulong, bool> mountDecoder; private static bool claimingDecoder; private static NetworkManager manager; private static CustomMessagingManager messages; private static SafeAuthority authority; private static ulong generation; private static ulong localNonce; private static ulong serverNonce; private static ulong levelNonce; private static bool acknowledged; private static float nextHello; private static float nextWarning; private static readonly Dictionary<ulong, ulong> peers = new Dictionary<ulong, ulong>(); private static readonly HashSet<ulong> pendingHello = new HashSet<ulong>(); private static readonly Dictionary<ulong, double> nextStart = new Dictionary<ulong, double>(); private static readonly Dictionary<ulong, SafeSnapshot> states = new Dictionary<ulong, SafeSnapshot>(); private static readonly Dictionary<ulong, int> rewards = new Dictionary<ulong, int>(); private static readonly Dictionary<ulong, NetworkObject> rewardObjects = new Dictionary<ulong, NetworkObject>(); private static readonly Dictionary<ulong, int> pendingRewards = new Dictionary<ulong, int>(); private static readonly Dictionary<ulong, NetworkObject> pendingObjects = new Dictionary<ulong, NetworkObject>(); private static readonly Dictionary<ulong, float> pendingExpires = new Dictionary<ulong, float>(); private static readonly Dictionary<ulong, NetworkObject> appliedRewards = new Dictionary<ulong, NetworkObject>(); private static readonly Dictionary<ulong, NetworkObject> statisticsRecorded = new Dictionary<ulong, NetworkObject>(); private static long statisticsTotal; private static long statisticsApplied; private static bool initialStatisticsReady; private static Action<ulong> disconnect; private static Action<bool> stopped; public static event Action<ulong> OnOpened; public static event Action<ulong, int> OnRewardValue; public static event Action<int> OnStatisticsDelta; public static void Initialize(SafeNetworkOptions settings, Func<ulong, int?> readCurrentRewardValue = null, Func<ulong, ulong, ulong, bool> validateAndMountDecoder = null) { options = (settings ?? throw new ArgumentNullException("settings")).ValidatedCopy(); currentRewardValue = readCurrentRewardValue; mountDecoder = validateAndMountDecoder; } public static bool TryGetState(ulong id, out SafeSnapshot state) { if (authority != null && (Object)(object)manager != (Object)null && manager.IsServer) { return authority.TryGetState(id, out state); } if (states.TryGetValue(id, out var value)) { state = value.Copy(); return true; } state = null; return false; } public static bool RegisterHostSafe(ulong id, int requiredSteps = 0) { bool registered = false; Guard(delegate { if (EnsureBound() && manager.IsServer && ObjectExists(id) && authority.Register(id, requiredSteps)) { registered = true; Publish(id, mayOpen: false); } }); return registered; } public static void ResetLevel() { Guard(delegate { if (!EnsureBound() || !manager.IsServer) { return; } if (levelNonce == ulong.MaxValue) { throw new InvalidOperationException("Level epochs exhausted."); } authority.Reset(++levelNonce); states.Clear(); nextStart.Clear(); statisticsRecorded.Clear(); statisticsTotal = (statisticsApplied = 0L); initialStatisticsReady = false; PruneRewards(); foreach (ulong item in new List<ulong>(peers.Keys)) { pendingHello.Add(item); try { SendAck(item); } catch (Exception ex) { Warn(ex); } } }); } public static void RequestStart(ulong id) { Request(0, id); } public static void RequestHit(ulong id) { Request(1, id); } public static void RequestHit(ulong id, ulong attempt, int step, double inputTime) { Guard(delegate { if (EnsureBound() && (manager.IsServer || acknowledged) && QteMath.IsFinite(inputTime) && TryGetState(id, out var state) && state.Mode == SafeMode.Active && state.OperatorClientId == manager.LocalClientId && state.AttemptToken == attempt && state.Step == step) { SendRequest(1, id, attempt, step, inputTime); } }); } public static void Cancel(ulong id) { Request(2, id); } public static void RequestDecoder(ulong id, ulong decoderObjectId) { Guard(delegate { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (EnsureBound() && (manager.IsServer || acknowledged) && decoderObjectId != ulong.MaxValue && TryGetState(id, out var state) && (state.Mode == SafeMode.Closed || state.Mode == SafeMode.Jammed)) { ulong id2 = id; ulong attempt = decoderObjectId; int revision = state.Revision; NetworkTime serverTime = manager.ServerTime; SendRequest(3, id2, attempt, revision, ((NetworkTime)(ref serverTime)).Time); } }); } public static bool ReleaseConsumedDecoder(ulong decoderObjectId) { bool released = false; Guard(delegate { if (EnsureBound() && manager.IsServer && !((Object)(object)CurrentObject(decoderObjectId) != (Object)null)) { released = authority.ReleaseConsumedDecoder(decoderObjectId); } }); return released; } public static void ResetInitialStatisticsReady() { Guard(delegate { if (EnsureBound()) { initialStatisticsReady = false; statisticsApplied = 0L; if (!manager.IsServer) { localNonce = NewNonce(); acknowledged = false; nextHello = 0f; } } }); } public static void MarkInitialStatisticsReady() { Guard(delegate { if (EnsureBound()) { initialStatisticsReady = true; statisticsApplied = 0L; FlushStatistics(); if (manager.IsServer) { BroadcastStatistics(); } } }); } public static void RecordStatisticsAdded(ulong objectId, int value) { Guard(delegate { if (EnsureBound() && manager.IsServer && value >= 0 && ObjectExists(objectId)) { NetworkObject val = CurrentObject(objectId); if (!statisticsRecorded.TryGetValue(objectId, out var value2) || value2 != val) { long num = checked(statisticsTotal + value); if (num > 8796093018112L) { throw new InvalidOperationException("Safe reward statistics exceed the protocol limit."); } statisticsRecorded[objectId] = val; statisticsTotal = num; FlushStatistics(); if (initialStatisticsReady) { BroadcastStatistics(); } } } }); } private static void Request(byte kind, ulong id) { Guard(delegate { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (EnsureBound() && (manager.IsServer || acknowledged)) { ulong num = 0uL; int num2 = 0; if (TryGetState(id, out var state)) { num = state.AttemptToken; num2 = ((kind == 0) ? state.Revision : state.Step); byte kind2 = kind; ulong id2 = id; ulong attempt = num; int step = num2; NetworkTime serverTime = manager.ServerTime; SendRequest(kind2, id2, attempt, step, ((NetworkTime)(ref serverTime)).Time); } } }); } private unsafe static void SendRequest(byte kind, ulong id, ulong attempt, int step, double inputTime) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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) if (manager.IsServer) { Execute(kind, manager.LocalClientId, id, attempt, step, inputTime); return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(64, (Allocator)2, -1); try { byte b = 4; ((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref b, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref kind, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref localNonce, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref serverNonce, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref levelNonce, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref id, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref attempt, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref step, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref inputTime, default(ForPrimitives)); messages.SendNamedMessage("Serenta.IndustrialGoldSafe.Command.4", 0uL, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } public static void RecordReward(ulong id, int value) { Guard(delegate { if (EnsureBound() && manager.IsServer && value >= 0 && ObjectExists(id)) { PruneRewards(); if (!rewards.ContainsKey(id)) { rewards.Add(id, value); rewardObjects[id] = CurrentObject(id); QueueReward(id, value); FlushRewards(); foreach (ulong item in new List<ulong>(peers.Keys)) { try { SendReward(item, id, value); } catch (Exception ex) { pendingHello.Add(item); Warn(ex); } } } } }); } public unsafe static void Tick() { Guard(delegate { //IL_0021: 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_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0227: 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_0240: Unknown result type (might be due to invalid IL or missing references) if (EnsureBound()) { PruneRewards(); if (manager.IsServer) { NetworkTime serverTime = manager.ServerTime; double time = ((NetworkTime)(ref serverTime)).Time; SafeSnapshot[] array = authority.Snapshot(); foreach (SafeSnapshot safeSnapshot in array) { if (authority.Tick(safeSnapshot.SafeId, time, Eligible(safeSnapshot.OperatorClientId, safeSnapshot.SafeId))) { Publish(safeSnapshot.SafeId, safeSnapshot.Mode != SafeMode.Open); } } foreach (ulong item in new List<ulong>(pendingHello)) { if (!Connected(item) || !peers.ContainsKey(item)) { pendingHello.Remove(item); } else { try { SendAck(item); array = authority.Snapshot(); foreach (SafeSnapshot s in array) { SendState(item, s); } foreach (KeyValuePair<ulong, int> item2 in new List<KeyValuePair<ulong, int>>(rewards)) { if (ObjectExists(item2.Key)) { int? num = ((currentRewardValue != null) ? currentRewardValue(item2.Key) : ReadLiveReward(item2.Key)); if (num.HasValue && num.Value >= 0) { SendReward(item, item2.Key, num.Value); } } } if (initialStatisticsReady) { SendStatistics(item); } pendingHello.Remove(item); } catch (Exception ex) { Warn(ex); } } } } else if (!acknowledged && Time.realtimeSinceStartup >= nextHello) { nextHello = Time.realtimeSinceStartup + 2f; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(9, (Allocator)2, -1); try { byte b = 4; ((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref b, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref localNonce, default(ForPrimitives)); messages.SendNamedMessage("Serenta.IndustrialGoldSafe.Hello.4", 0uL, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } FlushRewards(); FlushStatistics(); } }); } private static bool EnsureBound() { //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown NetworkManager current = NetworkManager.Singleton; if ((Object)(object)current == (Object)null || !current.IsListening || (!current.IsServer && !current.IsConnectedClient) || current.CustomMessagingManager == null) { if ((Object)(object)manager != (Object)null) { Shutdown(); } return false; } if (current == manager && messages == current.CustomMessagingManager) { return true; } Shutdown(); manager = current; messages = current.CustomMessagingManager; localNonce = NewNonce(); serverNonce = (current.IsServer ? NewNonce() : 0); levelNonce = (ulong)(current.IsServer ? 1 : 0); authority = (current.IsServer ? new SafeAuthority(options, levelNonce, (int)serverNonce) : null); ulong captured = generation; try { messages.RegisterNamedMessageHandler("Serenta.IndustrialGoldSafe.Hello.4", (HandleNamedMessageDelegate)delegate(ulong sender, FastBufferReader reader) { //IL_000e: 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 (IsCurrent(current, captured)) { Guard(delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ReceiveHello(sender, reader); }); } }); messages.RegisterNamedMessageHandler("Serenta.IndustrialGoldSafe.Command.4", (HandleNamedMessageDelegate)delegate(ulong sender, FastBufferReader reader) { //IL_000e: 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 (IsCurrent(current, captured)) { Guard(delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ReceiveCommand(sender, reader); }); } }); messages.RegisterNamedMessageHandler("Serenta.IndustrialGoldSafe.Event.4", (HandleNamedMessageDelegate)delegate(ulong sender, FastBufferReader reader) { //IL_000e: 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 (IsCurrent(current, captured)) { Guard(delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ReceiveEvent(sender, reader); }); } }); disconnect = delegate(ulong id) { if (IsCurrent(current, captured)) { peers.Remove(id); pendingHello.Remove(id); nextStart.Remove(id); if (id == current.LocalClientId || (!current.IsServer && id == 0L)) { Shutdown(); } } }; stopped = delegate { if (manager == current && generation == captured) { Shutdown(); } }; current.OnClientDisconnectCallback += disconnect; current.OnServerStopped += stopped; current.OnClientStopped += stopped; Log.LogInfo((object)("Safe messaging bound; authority=" + current.IsServer)); } catch { Shutdown(); throw; } return true; } public static void Shutdown() { generation++; if (messages != null) { string[] array = new string[3] { "Serenta.IndustrialGoldSafe.Hello.4", "Serenta.IndustrialGoldSafe.Command.4", "Serenta.IndustrialGoldSafe.Event.4" }; foreach (string text in array) { try { messages.UnregisterNamedMessageHandler(text); } catch (Exception ex) { Warn(ex); } } } if ((Object)(object)manager != (Object)null) { if (disconnect != null) { manager.OnClientDisconnectCallback -= disconnect; } if (stopped != null) { manager.OnServerStopped -= stopped; manager.OnClientStopped -= stopped; } } manager = null; messages = null; authority = null; disconnect = null; stopped = null; peers.Clear(); pendingHello.Clear(); nextStart.Clear(); states.Clear(); rewards.Clear(); rewardObjects.Clear(); pendingRewards.Clear(); pendingObjects.Clear(); pendingExpires.Clear(); appliedRewards.Clear(); statisticsRecorded.Clear(); statisticsTotal = (statisticsApplied = 0L); initialStatisticsReady = false; localNonce = (serverNonce = (levelNonce = 0uL)); acknowledged = false; nextHello = 0f; } private static bool IsCurrent(NetworkManager source, ulong captured) { if (manager == source && generation == captured) { return source.IsListening; } return false; } private static ulong NewNonce() { ulong num = BitConverter.ToUInt64(Guid.NewGuid().ToByteArray(), 0); if (num != 0L) { return num; } return 1uL; } private static bool Connected(ulong id) { if ((Object)(object)manager == (Object)null) { return false; } foreach (ulong connectedClientsId in manager.ConnectedClientsIds) { if (connectedClientsId == id) { return true; } } return false; } private static bool ObjectExists(ulong id) { if ((Object)(object)manager != (Object)null && manager.SpawnManager != null && manager.SpawnManager.SpawnedObjects.TryGetValue(id, out var value) && (Object)(object)value != (Object)null) { return value.IsSpawned; } return false; } private static NetworkObject CurrentObject(ulong id) { if (!ObjectExists(id)) { return null; } return manager.SpawnManager.SpawnedObjects[id]; } private static bool Eligible(ulong client, ulong id) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (!Connected(client) || !ObjectExists(id) || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null) { return false; } NetworkObject val = manager.SpawnManager.SpawnedObjects[id]; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val2 in allPlayerScripts) { if ((Object)(object)val2 != (Object)null && val2.actualClientId == client && val2.isPlayerControlled && !val2.isPlayerDead && val2.isInsideFactory) { Vector3 val3 = ((Component)val2).transform.position - ((Component)val).transform.position; return (double)((Vector3)(ref val3)).sqrMagnitude <= options.InteractionDistance * options.InteractionDistance; } } return false; } private static int? ReadLiveReward(ulong id) { if (!ObjectExists(id)) { return null; } GrabbableObject component = ((Component)manager.SpawnManager.SpawnedObjects[id]).GetComponent<GrabbableObject>(); if (!((Object)(object)component != (Object)null)) { return null; } return component.scrapValue; } private static void ReceiveHello(ulong sender, FastBufferReader reader) { //IL_003e: 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_0050: 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) if (manager.IsServer && sender != manager.LocalClientId && Connected(sender) && ((FastBufferReader)(ref reader)).Length == 9 && ((FastBufferReader)(ref reader)).TryBeginRead(9)) { byte b = default(byte); ((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref b, default(ForPrimitives)); ulong num = default(ulong); ((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num, default(ForPrimitives)); if (b == 4 && num != 0L) { peers[sender] = num; pendingHello.Add(sender); } } } private static void ReceiveCommand(ulong sender, FastBufferReader reader) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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) //IL_0079: 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_008c: 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_009f: 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_00b2: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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) if (manager.IsServer && Connected(sender) && peers.TryGetValue(sender, out var value) && ((FastBufferReader)(ref reader)).Length == 54 && ((FastBufferReader)(ref reader)).TryBeginRead(54)) { byte b = default(byte); ((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref b, default(ForPrimitives)); byte b2 = default(byte); ((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref b2, default(ForPrimitives)); ulong num = default(ulong); ((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num, default(ForPrimitives)); ulong num2 = default(ulong); ((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num2, default(ForPrimitives)); ulong num3 = default(ulong); ((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num3, default(ForPrimitives)); ulong id = default(ulong); ((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref id, default(ForPrimitives)); ulong token = default(ulong); ((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref token, default(ForPrimitives)); int step = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref step, default(ForPrimitives)); double time = default(double); ((FastBufferReader)(ref reader)).ReadValueSafe<double>(ref time, default(ForPrimitives)); if (b == 4 && b2 <= 3 && num == value && num2 == serverNonce && num3 == levelNonce) { Execute(b2, sender, id, token, step, time); } } } private static void Execute(byte kind, ulong sender, ulong id, ulong token, int step, double time) { //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) if (claimingDecoder || !authority.TryGetState(id, out var state)) { return; } NetworkTime serverTime = manager.ServerTime; double time2 = ((NetworkTime)(ref serverTime)).Time; bool flag = false; switch (kind) { case 0: { if (state.Mode != SafeMode.Closed || token != state.AttemptToken || step != state.Revision || (nextStart.TryGetValue(sender, out var value) && time2 < value)) { return; } nextStart[sender] = time2 + 0.25; flag = authority.Start(id, sender, time2, Eligible(sender, id)); break; } case 1: flag = authority.Hit(id, sender, token, step, time, time2, Eligible(sender, id)); break; case 2: flag = authority.Cancel(id, sender, token, step); break; case 3: if (!QteMath.IsFinite(time2) || !Eligible(sender, id) || mountDecoder == null || !authority.CanStartDecoder(id, token, step)) { return; } claimingDecoder = true; try { if (!mountDecoder(sender, id, token)) { return; } flag = authority.StartDecoder(id, sender, token, step, time2); if (!flag) { throw new InvalidOperationException("A validated decoder claim could not commit."); } } finally { claimingDecoder = false; } break; } if (flag) { Publish(id, state.Mode != SafeMode.Open); } } private static void Publish(ulong id, bool mayOpen) { if (!authority.TryGetState(id, out var state)) { return; } states[id] = state; foreach (ulong item in new List<ulong>(peers.Keys)) { try { SendState(item, state); } catch (Exception ex) { pendingHello.Add(item); Warn(ex); } } if (!mayOpen || state.Mode != SafeMode.Open || SafeNetworking.OnOpened == null) { return; } Delegate[] invocationList = SafeNetworking.OnOpened.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<ulong> action = (Action<ulong>)invocationList[i]; try { action(id); } catch (Exception ex2) { Warn(ex2); } } } private static void Header(FastBufferWriter writer, byte kind, ulong peer) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) byte b = 4; ((FastBufferWriter)(ref writer)).WriteValueSafe<byte>(ref b, default(ForPrimitives)); ((FastBufferWriter)(ref writer)).WriteValueSafe<byte>(ref kind, default(ForPrimitives)); ulong num = peers[peer]; ((FastBufferWriter)(ref writer)).WriteValueSafe<ulong>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref writer)).WriteValueSafe<ulong>(ref serverNonce, default(ForPrimitives)); ((FastBufferWriter)(ref writer)).WriteValueSafe<ulong>(ref levelNonce, default(ForPrimitives)); } private unsafe static void SendAck(ulong peer) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (!Connected(peer) || !peers.ContainsKey(peer)) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(26, (Allocator)2, -1); try { Header(val, 0, peer); messages.SendNamedMessage("Serenta.IndustrialGoldSafe.Event.4", peer, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private unsafe static void SendState(ulong peer, SafeSnapshot s) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_019f: 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_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: 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) if (!Connected(peer) || !peers.ContainsKey(peer)) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(176, (Allocator)2, -1); try { Header(val, 1, peer); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref s.SafeId, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref s.Revision, default(ForPrimitives)); byte mode = (byte)s.Mode; ((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref mode, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref s.OperatorClientId, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref s.AttemptToken, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref s.Step, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref s.Failures, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref s.RequiredSteps, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref s.JamChancePerFailure, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref s.StepStartTime, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref s.Deadline, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref s.TargetCenter, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref s.PeriodSeconds, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref s.TargetWidth, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref s.PhaseAtStart, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref s.EdgeToleranceSeconds, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref s.NextPeriodSeconds, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref s.DecoderObjectId, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref s.DecoderInstallerClientId, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref s.DecodeStartedAt, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref s.DecodeDeadline, default(ForPrimitives)); messages.SendNamedMessage("Serenta.IndustrialGoldSafe.Event.4", peer, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private unsafe static void SendReward(ulong peer, ulong id, int value) { //IL_0021: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (!Connected(peer) || !peers.ContainsKey(peer)) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(38, (Allocator)2, -1); try { Header(val, 2, peer); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref id, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref value, default(ForPrimitives)); messages.SendNamedMessage("Serenta.IndustrialGoldSafe.Event.4", peer, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private unsafe static void SendStatistics(ulong peer) { //IL_0028: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (!initialStatisticsReady || !Connected(peer) || !peers.ContainsKey(peer)) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(34, (Allocator)2, -1); try { Header(val, 3, peer); ((FastBufferWriter)(ref val)).WriteValueSafe<long>(ref statisticsTotal, default(ForPrimitives)); messages.SendNamedMessage("Serenta.IndustrialGoldSafe.Event.4", peer, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private static void BroadcastStatistics() { foreach (ulong item in new List<ulong>(peers.Keys)) { try { SendStatistics(item); } catch (Exception ex) { pendingHello.Add(item); Warn(ex); } } } private static void ReceiveEvent(ulong sender, FastBufferReader reader) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result ty