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 Pockets v1.0.1
Pockets.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using Pockets.Api; using Pockets.Domain; using Pockets.Net; using Pockets.Ui; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("Osmar Briones")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+b89fdcfa9af60dd2cfac68d7713632ae2f78249e")] [assembly: AssemblyProduct("Pockets")] [assembly: AssemblyTitle("Pockets")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Pockets { internal class ConfigurationController { private static ConfigFile? ConfigFile { get; set; } private static ConfigEntry<bool>? Enabled { get; set; } private static ConfigEntry<PocketSize>? MaxValuableSizeEntry { get; set; } private static ConfigEntry<bool>? DropOnDeathEntry { get; set; } private static ConfigEntry<bool>? ShowSlotValueEntry { get; set; } private static ConfigEntry<bool>? EnableIconBake { get; set; } internal static bool IsEnabled => Enabled?.Value ?? true; internal static PocketSize LocalMaxValuableSize => MaxValuableSizeEntry?.Value ?? PocketSize.Tiny; internal static bool LocalDropOnDeath => DropOnDeathEntry?.Value ?? true; internal static PocketSize MaxValuableSize { get { if (!HostSettings.TryGetMaxSize(out var size)) { return LocalMaxValuableSize; } return size; } } internal static bool DropOnDeath { get { if (!HostSettings.TryGetDropOnDeath(out var drop)) { return LocalDropOnDeath; } return drop; } } internal static bool ShowSlotValue { get { ConfigEntry<bool>? showSlotValueEntry = ShowSlotValueEntry; if (showSlotValueEntry != null && !showSlotValueEntry.Value) { return PocketsApi.SlotValueRequired; } return true; } } internal static bool IconBakeEnabled => EnableIconBake?.Value ?? false; internal static void Initialize(ConfigFile config) { ConfigFile = config; Enabled = ConfigFile.Bind<bool>("General", "Enabled", true, "Enable or disable this mod. Turning it off drops whatever is in your pockets."); Enabled.SettingChanged += delegate { OnEnabledChanged(); }; MaxValuableSizeEntry = ConfigFile.Bind<PocketSize>("General", "MaxValuableSize", PocketSize.Tiny, "Largest valuable that can be stored in a pocket. Every size up to this one is accepted (Tiny, Small, Medium, Big, Wide, Tall, VeryTall). The host's value is used."); DropOnDeathEntry = ConfigFile.Bind<bool>("General", "DropOnDeath", true, "Drop the valuables stored in your pockets where you die. The host's value is used."); ShowSlotValueEntry = ConfigFile.Bind<bool>("Display", "ShowSlotValue", true, "Show the stored valuable's current value on its inventory slot. Other mods that depend on the value turn it on regardless of this setting."); EnableIconBake = ConfigFile.Bind<bool>("Debug", "EnableIconBake", false, "Developer only. Press F10 inside a level to render a picture of every valuable to BepInEx/PocketIcons."); ConfigFile.Save(); } private static void OnEnabledChanged() { if (!IsEnabled) { PocketReleaser.ReleaseLocalPockets(); } } internal static void Reload() { ConfigFile? configFile = ConfigFile; if (configFile != null) { configFile.Reload(); } ConfigFile? configFile2 = ConfigFile; if (configFile2 != null) { configFile2.Save(); } } } [BepInPlugin("com.osmar.Pockets", "Pockets", "1.0.1")] public class PocketsPlugin : BaseUnityPlugin { public const string PluginGuid = "com.osmar.Pockets"; public const string PluginName = "Pockets"; public const string PluginVersion = "1.0.1"; internal Harmony? Harmony { get; set; } internal static ManualLogSource Logger { get; private set; } private void Awake() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; ConfigurationController.Initialize(((BaseUnityPlugin)this).Config); ((Component)this).gameObject.AddComponent<PocketsRoomEvents>(); if (ConfigurationController.IconBakeEnabled) { ((Component)this).gameObject.AddComponent<IconBaker>(); Logger.LogWarning((object)"Icon baking is enabled (Debug.EnableIconBake): press F10 inside a level. Developer use only."); } Harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony.PatchAll(); Logger.LogInfo((object)"Pockets 1.0.1 loaded!"); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } namespace Pockets.Ui { internal sealed class IconBaker : MonoBehaviour { private static readonly string[] Folders = new string[7] { "valuables/01 tiny", "valuables/02 small", "valuables/03 medium", "valuables/04 big", "valuables/05 wide", "valuables/06 tall", "valuables/07 very tall" }; private const int BakeSize = 256; private bool running; private void Update() { Keyboard current = Keyboard.current; if (current != null && ((ButtonControl)current.f10Key).wasPressedThisFrame && !running) { ((MonoBehaviour)this).StartCoroutine(Bake()); } } private IEnumerator Bake() { running = true; string outputFolder = Path.Combine(Paths.BepInExRootPath, "PocketIcons"); Directory.CreateDirectory(outputFolder); PocketsPlugin.Logger.LogInfo((object)("[Icon bake] started, writing to " + outputFolder)); int saved = 0; int failed = 0; string[] folders = Folders; foreach (string text in folders) { GameObject[] array = Resources.LoadAll<GameObject>(text); PocketsPlugin.Logger.LogInfo((object)$"[Icon bake] {text}: {array.Length} prefabs"); GameObject[] array2 = array; foreach (GameObject val in array2) { string text2 = ValuableIconRenderer.KeyOf(val); Texture2D val2 = null; try { val2 = ValuableIconRenderer.RenderTexture2D(val, 256); if ((Object)(object)val2 != (Object)null) { File.WriteAllBytes(Path.Combine(outputFolder, text2 + ".png"), ImageConversion.EncodeToPNG(val2)); saved++; } else { failed++; PocketsPlugin.Logger.LogWarning((object)("[Icon bake] nothing to draw for " + text2)); } } catch (Exception ex) { failed++; PocketsPlugin.Logger.LogWarning((object)("[Icon bake] " + text2 + " failed: " + ex.Message)); } finally { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } } yield return null; } } PocketsPlugin.Logger.LogInfo((object)$"[Icon bake] done: {saved} saved, {failed} failed"); running = false; } } internal sealed class PocketSlotView : MonoBehaviour { private const float LabelRefreshSeconds = 0.25f; private InventorySpot spot; private TextMeshProUGUI? valueLabel; private float nextLabelRefresh; internal static PocketSlotView GetOrAdd(InventorySpot spot) { PocketSlotView pocketSlotView = ((Component)spot).GetComponent<PocketSlotView>(); if ((Object)(object)pocketSlotView == (Object)null) { pocketSlotView = ((Component)spot).gameObject.AddComponent<PocketSlotView>(); } return pocketSlotView; } private void Awake() { spot = ((Component)this).GetComponent<InventorySpot>(); } private void Update() { if (!(Time.unscaledTime < nextLabelRefresh)) { nextLabelRefresh = Time.unscaledTime + 0.25f; ValuableObject val = CurrentValuable(); if ((Object)(object)val != (Object)null) { ShowLabel(val); } } } internal void Refresh() { ValuableObject val = CurrentValuable(); if ((Object)(object)val == (Object)null) { HideLabel(); return; } spot.SetEmoji(ValuableIconRenderer.Get(((Component)val).gameObject)); ShowLabel(val); } private ValuableObject? CurrentValuable() { if ((Object)(object)spot == (Object)null || !SemiFunc.RunIsLevel()) { return null; } int num = PlayerKeys.Local(); if (num == int.MinValue) { return null; } PlayerPockets playerPockets = PocketsApi.Find(num); int inventorySpotIndex = spot.inventorySpotIndex; if (playerPockets == null || inventorySpotIndex < 0 || inventorySpotIndex >= playerPockets.Valuables.Length) { return null; } return playerPockets.Valuables[inventorySpotIndex]; } private void ShowLabel(ValuableObject valuable) { if (!ConfigurationController.ShowSlotValue) { HideLabel(); return; } TextMeshProUGUI val = EnsureLabel(); if (!((Object)(object)val == (Object)null)) { ((TMP_Text)val).text = FormatValue(valuable.dollarValueCurrent); ((Behaviour)val).enabled = true; } } private void HideLabel() { if ((Object)(object)valueLabel != (Object)null) { ((Behaviour)valueLabel).enabled = false; } } private TextMeshProUGUI? EnsureLabel() { //IL_00a4: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)valueLabel != (Object)null) { return valueLabel; } TextMeshProUGUI noItem = spot.noItem; if ((Object)(object)noItem == (Object)null) { return null; } valueLabel = Object.Instantiate<TextMeshProUGUI>(noItem, ((TMP_Text)noItem).transform.parent); ((Object)valueLabel).name = "PocketValue"; ((TMP_Text)valueLabel).alignment = (TextAlignmentOptions)514; ((TMP_Text)valueLabel).enableAutoSizing = false; ((TMP_Text)valueLabel).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)valueLabel).overflowMode = (TextOverflowModes)0; ((TMP_Text)valueLabel).fontSize = ((TMP_Text)noItem).fontSize * 0.55f; ((Graphic)valueLabel).color = Color.white; ((Graphic)valueLabel).raycastTarget = false; ((TMP_Text)valueLabel).outlineWidth = 0.3f; ((TMP_Text)valueLabel).outlineColor = new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue); if ((Object)(object)spot.inventoryIcon != (Object)null) { RectTransform rectTransform = ((Graphic)spot.inventoryIcon).rectTransform; float num = ((TMP_Text)valueLabel).fontSize * 0.7f; RectTransform rectTransform2 = ((TMP_Text)valueLabel).rectTransform; Vector2 anchoredPosition = rectTransform.anchoredPosition; Rect rect = rectTransform.rect; rectTransform2.anchoredPosition = anchoredPosition + new Vector2(0f, ((Rect)(ref rect)).yMin + num); } return valueLabel; } private static string FormatValue(float value) { if (!(value >= 1000f)) { return "$" + value.ToString("0", CultureInfo.InvariantCulture); } return "$" + (value / 1000f).ToString("0.#", CultureInfo.InvariantCulture) + "K"; } } internal static class ValuableIconRenderer { private readonly struct Part { internal Mesh Mesh { get; } internal Material[] Materials { get; } internal Matrix4x4 Matrix { get; } internal Part(Mesh mesh, Material[] materials, Matrix4x4 matrix) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) Mesh = mesh; Materials = materials; Matrix = matrix; } } internal const int Size = 128; private const float FieldOfView = 30f; private const string EmbeddedPrefix = "Pockets.Icons."; private static readonly Vector3 FarOrigin = new Vector3(0f, 5000f, 0f); private static readonly Dictionary<string, Sprite> Cache = new Dictionary<string, Sprite>(); private static Sprite? fallback; internal static Sprite Fallback { get { if ((Object)(object)fallback == (Object)null) { fallback = CreateFallback(); } return fallback; } } internal static string KeyOf(GameObject valuable) { return ((Object)valuable).name.Replace("(Clone)", string.Empty).Trim(); } internal static void Ensure(GameObject valuable) { //IL_006c: 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) string text = KeyOf(valuable); if (Cache.TryGetValue(text, out Sprite value) && (Object)(object)value != (Object)null) { return; } Sprite val = LoadEmbedded(text); string text2 = "packaged"; if ((Object)(object)val == (Object)null) { text2 = "rendered"; try { Texture2D val2 = RenderTexture2D(valuable); val = (((Object)(object)val2 != (Object)null) ? Sprite.Create(val2, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f)) : null); } catch (Exception ex) { PocketsPlugin.Logger.LogWarning((object)("Could not render an icon for " + text + ": " + ex.Message)); } } if ((Object)(object)val == (Object)null) { text2 = "generic"; } PocketsPlugin.Logger.LogInfo((object)("Icon for " + text + ": " + text2)); Cache[text] = (Sprite)(((Object)(object)val != (Object)null) ? ((object)val) : ((object)Fallback)); } internal static Sprite Get(GameObject valuable) { if (!Cache.TryGetValue(KeyOf(valuable), out Sprite value) || !((Object)(object)value != (Object)null)) { return Fallback; } return value; } private static Sprite? LoadEmbedded(string key) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Pockets.Icons." + key + ".png"); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!TryDecodePng(val, array)) { Object.Destroy((Object)(object)val); return null; } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } catch (Exception ex) { PocketsPlugin.Logger.LogWarning((object)("Could not load the packaged icon for " + key + ": " + ex.Message)); return null; } } private static bool TryDecodePng(Texture2D texture, byte[] bytes) { MethodInfo method = typeof(ImageConversion).GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(Texture2D), typeof(byte[]) }, null); if (method != null) { object obj = method.Invoke(null, new object[2] { texture, bytes }); if (obj is bool) { return (bool)obj; } return false; } return false; } internal static Texture2D? RenderTexture2D(GameObject source, int size = 128) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: 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_007d: Unknown result type (might be due to invalid IL or missing references) //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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: 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_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02da: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Expected O, but got Unknown //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) List<Part> list = new List<Part>(); Bounds bounds = default(Bounds); bool flag = false; Matrix4x4 worldToLocalMatrix = source.transform.worldToLocalMatrix; MeshRenderer[] componentsInChildren = source.GetComponentsInChildren<MeshRenderer>(); MeshFilter val2 = default(MeshFilter); foreach (MeshRenderer val in componentsInChildren) { if (!((Renderer)val).enabled || !((Component)val).gameObject.activeSelf || !((Component)val).TryGetComponent<MeshFilter>(ref val2) || (Object)(object)val2.sharedMesh == (Object)null) { continue; } Material[] sharedMaterials = ((Renderer)val).sharedMaterials; if (sharedMaterials.Length != 0) { Matrix4x4 matrix = worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix; list.Add(new Part(val2.sharedMesh, sharedMaterials, matrix)); Bounds val3 = TransformBounds(val2.sharedMesh.bounds, matrix); if (flag) { ((Bounds)(ref bounds)).Encapsulate(val3); continue; } bounds = val3; flag = true; } } if (!flag) { return null; } Vector3 val4 = ((Bounds)(ref bounds)).extents; float num = Mathf.Max(((Vector3)(ref val4)).magnitude, 0.001f); val4 = new Vector3(0.6f, 0.45f, -1f); Vector3 normalized = ((Vector3)(ref val4)).normalized; float num2 = FitDistance(bounds, normalized, num); Vector3 position = FarOrigin + normalized * num2; AmbientMode ambientMode = RenderSettings.ambientMode; Color ambientLight = RenderSettings.ambientLight; bool fog = RenderSettings.fog; RenderTexture val5 = new RenderTexture(size, size, 24, (RenderTextureFormat)0); GameObject val6 = new GameObject("PocketsIconCamera") { hideFlags = (HideFlags)61 }; GameObject val7 = new GameObject("PocketsIconLights") { hideFlags = (HideFlags)61 }; RenderTexture active = RenderTexture.active; try { RenderSettings.ambientMode = (AmbientMode)3; RenderSettings.ambientLight = new Color(0.55f, 0.55f, 0.55f); RenderSettings.fog = false; Camera val8 = val6.AddComponent<Camera>(); ((Behaviour)val8).enabled = false; val8.clearFlags = (CameraClearFlags)2; val8.backgroundColor = new Color(0f, 0f, 0f, 0f); val8.cullingMask = 1; val8.nearClipPlane = 0.001f; val8.farClipPlane = num2 + num * 4f; val8.fieldOfView = 30f; val8.allowHDR = false; val8.allowMSAA = false; val8.targetTexture = val5; ((Component)val8).transform.position = position; ((Component)val8).transform.LookAt(FarOrigin); AddLight(val7, "Key", 1f, Quaternion.LookRotation(new Vector3(-0.5f, -0.7f, 0.6f))); AddLight(val7, "Fill", 0.45f, Quaternion.LookRotation(new Vector3(0.7f, -0.2f, 0.5f))); foreach (Part item in list) { Matrix4x4 val9 = Matrix4x4.Translate(FarOrigin - ((Bounds)(ref bounds)).center) * item.Matrix; for (int j = 0; j < item.Mesh.subMeshCount; j++) { Graphics.DrawMesh(item.Mesh, val9, item.Materials[Mathf.Min(j, item.Materials.Length - 1)], 0, val8, j); } } val8.Render(); RenderTexture.active = val5; Texture2D val10 = new Texture2D(size, size, (TextureFormat)4, false); val10.ReadPixels(new Rect(0f, 0f, (float)size, (float)size), 0, 0); val10.Apply(); if (!HasVisiblePixels(val10)) { Object.Destroy((Object)(object)val10); return null; } return val10; } finally { RenderTexture.active = active; RenderSettings.ambientMode = ambientMode; RenderSettings.ambientLight = ambientLight; RenderSettings.fog = fog; Light[] componentsInChildren2 = val7.GetComponentsInChildren<Light>(); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Behaviour)componentsInChildren2[i]).enabled = false; } val7.SetActive(false); Object.Destroy((Object)(object)val7); Object.Destroy((Object)(object)val6); val5.Release(); Object.Destroy((Object)(object)val5); } } private static float FitDistance(Bounds bounds, Vector3 direction, float radius) { //IL_0011: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00c0: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Tan((float)Math.PI / 12f) * 0.94f; Vector3 val = -direction; Vector3 val2 = Vector3.Cross(Vector3.up, val); Vector3 normalized = ((Vector3)(ref val2)).normalized; Vector3 val3 = Vector3.Cross(val, normalized); float num2 = radius * 0.5f; for (int i = 0; i < 8; i++) { Vector3 val4 = new Vector3(((i & 1) == 0) ? (0f - ((Bounds)(ref bounds)).extents.x) : ((Bounds)(ref bounds)).extents.x, ((i & 2) == 0) ? (0f - ((Bounds)(ref bounds)).extents.y) : ((Bounds)(ref bounds)).extents.y, ((i & 4) == 0) ? (0f - ((Bounds)(ref bounds)).extents.z) : ((Bounds)(ref bounds)).extents.z); float num3 = Vector3.Dot(val4, normalized); float num4 = Vector3.Dot(val4, val3); float num5 = Vector3.Dot(val4, val); num2 = Mathf.Max(new float[3] { num2, Mathf.Abs(num3) / num - num5, Mathf.Abs(num4) / num - num5 }); } return num2 * 1.04f; } private static void AddLight(GameObject parent, string name, float intensity, Quaternion rotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0020: 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) GameObject val = new GameObject(name) { hideFlags = (HideFlags)61 }; val.transform.SetParent(parent.transform, false); val.transform.rotation = rotation; Light obj = val.AddComponent<Light>(); obj.type = (LightType)1; obj.intensity = intensity; obj.shadows = (LightShadows)0; obj.cullingMask = 1; } private static Bounds TransformBounds(Bounds local, Matrix4x4 matrix) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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) Vector3 val = ((Matrix4x4)(ref matrix)).MultiplyPoint3x4(((Bounds)(ref local)).center); Vector3 extents = ((Bounds)(ref local)).extents; Vector3 val2 = ((Matrix4x4)(ref matrix)).MultiplyVector(new Vector3(extents.x, 0f, 0f)); Vector3 val3 = ((Matrix4x4)(ref matrix)).MultiplyVector(new Vector3(0f, extents.y, 0f)); Vector3 val4 = ((Matrix4x4)(ref matrix)).MultiplyVector(new Vector3(0f, 0f, extents.z)); Vector3 val5 = default(Vector3); ((Vector3)(ref val5))..ctor(Mathf.Abs(val2.x) + Mathf.Abs(val3.x) + Mathf.Abs(val4.x), Mathf.Abs(val2.y) + Mathf.Abs(val3.y) + Mathf.Abs(val4.y), Mathf.Abs(val2.z) + Mathf.Abs(val3.z) + Mathf.Abs(val4.z)); return new Bounds(val, val5 * 2f); } private static bool HasVisiblePixels(Texture2D texture) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Color32[] pixels = texture.GetPixels32(); int num = 0; Color32[] array = pixels; for (int i = 0; i < array.Length; i++) { if (array[i].a > 12) { num++; } } return num > pixels.Length / 50; } private static Sprite CreateFallback() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color val2 = default(Color); ((Color)(ref val2))..ctor(0f, 0f, 0f, 0f); Color val3 = default(Color); ((Color)(ref val3))..ctor(1f, 0.82f, 0.25f, 1f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0.65f, 0.45f, 0.1f, 1f); float num = 31.5f; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num2 = Mathf.Abs((float)j - num) + Mathf.Abs((float)i - num); val.SetPixel(j, i, (num2 < num * 0.8f) ? val3 : ((num2 < num * 0.95f) ? val4 : val2)); } } val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } } } namespace Pockets.Patches { [HarmonyPatch(typeof(EnemyDirector), "Start")] internal static class EnemyDirector_Start_Patch { [HarmonyPostfix] private static void Postfix() { if (SemiFunc.RunIsLevel()) { ConfigurationController.Reload(); PocketsApi.ClearAll(); HostSettings.Publish(); } } } [HarmonyPatch(typeof(InventorySpot), "HandleInput")] internal static class InventorySpot_HandleInput_Patch { private const float RequestCooldownSeconds = 0.2f; private static float lastRequestTime = -1f; [HarmonyPrefix] private static bool Prefix(InventorySpot __instance) { if (!SemiFunc.RunIsLevel()) { return true; } int num = PlayerKeys.Local(); if (num == int.MinValue) { return true; } int inventorySpotIndex = __instance.inventorySpotIndex; PlayerPockets playerPockets = PocketsApi.Find(num); if (playerPockets != null && playerPockets.State.IsOccupied(inventorySpotIndex)) { if (CanSendRequest()) { ValuableObject val = playerPockets.Valuables[inventorySpotIndex]; PocketedValuable pocketedValuable = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<PocketedValuable>() : null); if ((Object)(object)pocketedValuable != (Object)null) { pocketedValuable.RequestRelease(); } else { PocketsPlugin.Logger.LogWarning((object)$"Slot {inventorySpotIndex + 1} held a valuable that no longer exists; freeing the slot."); PocketsApi.Forget(num, inventorySpotIndex); } } return false; } if (!ConfigurationController.IsEnabled || __instance.IsOccupied()) { return true; } PocketedValuable pocketedValuable2 = HeldValuable(); if ((Object)(object)pocketedValuable2 == (Object)null || !PocketSync.IsSizeAccepted(pocketedValuable2.Valuable)) { return true; } if (CanSendRequest()) { PocketsPlugin.Logger.LogInfo((object)$"Slot {inventorySpotIndex + 1} pressed holding {((Object)pocketedValuable2).name}: asking to store it"); pocketedValuable2.RequestStore(inventorySpotIndex); } return false; } private static bool CanSendRequest() { if (PlayerController.instance.InputDisableTimer > 0f || Time.time - lastRequestTime < 0.2f) { return false; } lastRequestTime = Time.time; return true; } private static PocketedValuable? HeldValuable() { PhysGrabber instance = PhysGrabber.instance; if ((Object)(object)instance == (Object)null || !instance.grabbed || (Object)(object)instance.grabbedPhysGrabObject == (Object)null) { return null; } return ((Component)instance.grabbedPhysGrabObject).GetComponent<PocketedValuable>(); } } [HarmonyPatch(typeof(InventorySpot), "IsOccupied")] internal static class InventorySpot_Occupied_Patch { [HarmonyPostfix] private static void Postfix(InventorySpot __instance, ref bool __result) { if (__result || !SemiFunc.RunIsLevel()) { return; } int num = PlayerKeys.Local(); if (num != int.MinValue) { PlayerPockets playerPockets = PocketsApi.Find(num); if (playerPockets != null && playerPockets.State.IsOccupied(__instance.inventorySpotIndex)) { __result = true; } } } } [HarmonyPatch(typeof(InventorySpot), "UpdateUI")] internal static class InventorySpot_UI_Patch { [HarmonyPostfix] private static void Postfix(InventorySpot __instance) { PocketSlotView.GetOrAdd(__instance).Refresh(); } } [HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathRPC")] internal static class PlayerAvatar_PlayerDeathRPC_Patch { [HarmonyPrefix] private static void Prefix(PlayerAvatar __instance, out bool __state) { __state = __instance.deadSet; } [HarmonyPostfix] private static void Postfix(PlayerAvatar __instance, bool __state) { if (__state || !__instance.deadSet || !SemiFunc.IsMasterClientOrSingleplayer()) { return; } int playerKey = PlayerKeys.Of(__instance); PlayerPockets playerPockets = PocketsApi.Find(playerKey); if (playerPockets != null && playerPockets.State.OccupiedCount != 0 && !PocketsApi.RaisePlayerDying(playerKey) && ConfigurationController.DropOnDeath) { for (int i = 0; i < playerPockets.Valuables.Length; i++) { PocketsApi.TryRemove(playerKey, i); } } } } [HarmonyPatch(typeof(ValuableObject), "AddToDollarHaulList")] internal static class ValuableObject_AddToDollarHaulList_Patch { [HarmonyPrefix] private static bool Prefix(ValuableObject __instance) { PocketedValuable component = ((Component)__instance).GetComponent<PocketedValuable>(); if (!((Object)(object)component == (Object)null)) { return !component.IsPocketed; } return true; } } [HarmonyPatch(typeof(ValuableObject), "Start")] internal static class ValuableObject_Start_Patch { [HarmonyPostfix] private static void Postfix(ValuableObject __instance) { if (!((Object)(object)((Component)__instance).GetComponent<PocketedValuable>() != (Object)null)) { ((Component)__instance).gameObject.AddComponent<PocketedValuable>(); PhotonView component = ((Component)__instance).GetComponent<PhotonView>(); if ((Object)(object)component != (Object)null) { component.RefreshRpcMonoBehaviourCache(); } } } } } namespace Pockets.Net { internal static class HostSettings { private const string MaxSizeKey = "pockets.maxSize"; private const string DropOnDeathKey = "pockets.dropOnDeath"; private static bool UseHostValues { get { if (PhotonNetwork.InRoom) { return !PhotonNetwork.IsMasterClient; } return false; } } internal static void Publish() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_004a: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient) { Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"pockets.maxSize", (object)(int)ConfigurationController.LocalMaxValuableSize); ((Dictionary<object, object>)val).Add((object)"pockets.dropOnDeath", (object)ConfigurationController.LocalDropOnDeath); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } internal static bool TryGetMaxSize(out PocketSize size) { size = PocketSize.Tiny; if (!UseHostValues || !((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"pockets.maxSize", out object value) || !(value is int gameVolume)) { return false; } return SizePolicy.TryFromGameVolume(gameVolume, out size); } internal static bool TryGetDropOnDeath(out bool drop) { drop = true; if (!UseHostValues || !((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"pockets.dropOnDeath", out object value) || !(value is bool flag)) { return false; } drop = flag; return true; } } internal static class PlayerKeys { internal const int SingleplayerKey = -1; internal const int NoPlayer = int.MinValue; internal static int Of(PlayerAvatar avatar) { if (!SemiFunc.IsMultiplayer()) { return -1; } return avatar.photonView.ViewID; } internal static int Local() { PlayerAvatar instance = PlayerAvatar.instance; if (!((Object)(object)instance == (Object)null)) { return Of(instance); } return int.MinValue; } internal static PlayerAvatar? Resolve(int playerKey) { if (!SemiFunc.IsMultiplayer()) { return PlayerAvatar.instance; } return SemiFunc.PlayerAvatarGetFromPhotonID(playerKey); } } internal sealed class PocketedValuable : MonoBehaviourPun { private const float HiddenScaleFactor = 0.01f; private const float ReleaseDistance = 1.5f; private const float MaxReleaseDistanceFromPlayer = 10f; private const float AutoGrabSeconds = 1.5f; private PhysGrabObject physGrabObject; private ValuableObject valuable; private Rigidbody? body; private Collider[] colliders = (Collider[])(object)new Collider[0]; private bool[] colliderStates = new bool[0]; private Vector3 originalScale = Vector3.one; private bool bodyWasKinematic; private float releaseOffset; internal ValuableObject Valuable => valuable; internal PhysGrabObject PhysGrabObject => physGrabObject; internal bool IsPocketed { get; private set; } internal int PlayerKey { get; private set; } = int.MinValue; internal int Slot { get; private set; } = -1; internal int Key { get { if (!SemiFunc.IsMultiplayer()) { return ((Object)((Component)this).gameObject).GetInstanceID(); } return ((MonoBehaviourPun)this).photonView.ViewID; } } private void Awake() { physGrabObject = ((Component)this).GetComponent<PhysGrabObject>(); valuable = ((Component)this).GetComponent<ValuableObject>(); body = ((Component)this).GetComponent<Rigidbody>(); } private void Update() { if (IsPocketed) { physGrabObject.OverrideDeactivate(0.1f); } } private void OnDestroy() { if (!IsPocketed) { return; } int playerKey = PlayerKey; int slot = Slot; int key = Key; PocketsApi.Forget(playerKey, slot); try { PocketsApi.RaiseRemoved(new PocketEvent(playerKey, slot, key, null)); RefreshLocalSlot(playerKey, slot); } catch (Exception ex) { PocketsPlugin.Logger.LogWarning((object)$"Could not refresh slot {slot} after {((Object)this).name} was destroyed: {ex.Message}"); } } internal void RequestStore(int slot) { PlayerAvatar instance = PlayerAvatar.instance; if (!((Object)(object)instance == (Object)null)) { int num = PlayerKeys.Of(instance); if (SemiFunc.IsMultiplayer()) { ((MonoBehaviourPun)this).photonView.RPC("RequestStoreRpc", (RpcTarget)2, new object[2] { slot, num }); } else { ProcessStoreRequest(slot, num); } } } [PunRPC] private void RequestStoreRpc(int slot, int playerKey, PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClient()) { PlayerAvatar val = PlayerKeys.Resolve(playerKey); if (!((Object)(object)val == (Object)null) && SemiFunc.MasterAndOwnerOnlyRPC(info, val.photonView)) { ProcessStoreRequest(slot, playerKey); } } } private void ProcessStoreRequest(int slot, int playerKey) { if (!PocketSync.CanStore(this, slot, playerKey, out string reason)) { PocketsPlugin.Logger.LogInfo((object)("Store refused for " + ((Object)this).name + ": " + reason)); } else if (SemiFunc.IsMultiplayer()) { ((MonoBehaviourPun)this).photonView.RPC("StoredRpc", (RpcTarget)0, new object[2] { playerKey, slot }); } else { ApplyStored(playerKey, slot); } } [PunRPC] private void StoredRpc(int playerKey, int slot, PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.MasterOnlyRPC(info)) { ApplyStored(playerKey, slot); } } private void ApplyStored(int playerKey, int slot) { PlayerPockets orCreate = PocketsApi.GetOrCreate(playerKey); if (IsPocketed || !orCreate.State.TryStore(slot, Key)) { PocketsPlugin.Logger.LogWarning((object)$"Could not register {((Object)this).name} in slot {slot} of player {playerKey}; ignoring the store."); return; } orCreate.Valuables[slot] = valuable; IsPocketed = true; PlayerKey = playerKey; Slot = slot; if (playerKey == PlayerKeys.Local()) { ValuableIconRenderer.Ensure(((Component)this).gameObject); } Hide(); PocketsPlugin.Logger.LogInfo((object)$"Stored {((Object)this).name} (value {valuable.dollarValueCurrent:F0}) in slot {slot} of player {playerKey}"); PocketsApi.RaiseStored(new PocketEvent(playerKey, slot, Key, valuable)); RefreshLocalSlot(playerKey, slot); } internal void SendStateTo(Player target, int playerKey, int slot) { if (SemiFunc.IsMultiplayer() && IsPocketed) { ((MonoBehaviourPun)this).photonView.RPC("StoredRpc", target, new object[2] { playerKey, slot }); } } internal void RequestRelease(bool autoGrab = true, int spread = 0) { //IL_0094: 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_0068: 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) PlayerAvatar instance = PlayerAvatar.instance; if (!((Object)(object)instance == (Object)null) && IsPocketed && PlayerKey == PlayerKeys.Of(instance)) { ComputeReleasePose(spread, out var position, out var rotation); if (SemiFunc.IsMultiplayer()) { ((MonoBehaviourPun)this).photonView.RPC("RequestReleaseRpc", (RpcTarget)2, new object[5] { Slot, PlayerKey, position, rotation, autoGrab }); } else { ProcessReleaseRequest(Slot, PlayerKey, position, rotation, autoGrab); } } } [PunRPC] private void RequestReleaseRpc(int slot, int playerKey, Vector3 position, Quaternion rotation, bool autoGrab, PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_0018: 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_002c: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClient()) { PlayerAvatar val = PlayerKeys.Resolve(playerKey); if (!((Object)(object)val == (Object)null) && SemiFunc.MasterAndOwnerOnlyRPC(info, val.photonView)) { ProcessReleaseRequest(slot, playerKey, position, rotation, autoGrab); } } } private void ProcessReleaseRequest(int slot, int playerKey, Vector3 position, Quaternion rotation, bool autoGrab) { //IL_000a: 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_003f: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar avatar = PlayerKeys.Resolve(playerKey); if (!PocketSync.CanRelease(this, slot, playerKey, position, avatar, 10f, out string reason)) { PocketsPlugin.Logger.LogInfo((object)("Release refused for " + ((Object)this).name + ": " + reason)); } else { BroadcastRelease(slot, playerKey, position, rotation, autoGrab); } } internal void BroadcastRelease(int slot, int playerKey, Vector3 position, Quaternion rotation, bool autoGrab) { //IL_0051: 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_002d: 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) if (SemiFunc.IsMultiplayer()) { ((MonoBehaviourPun)this).photonView.RPC("ReleasedRpc", (RpcTarget)0, new object[5] { playerKey, slot, position, rotation, autoGrab }); } else { ApplyReleased(playerKey, slot, position, rotation, autoGrab); } } [PunRPC] private void ReleasedRpc(int playerKey, int slot, Vector3 position, Quaternion rotation, bool autoGrab, PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.MasterOnlyRPC(info)) { ApplyReleased(playerKey, slot, position, rotation, autoGrab); } } private void ApplyReleased(int playerKey, int slot, Vector3 position, Quaternion rotation, bool autoGrab) { //IL_0097: 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) PlayerPockets playerPockets = PocketsApi.Find(playerKey); if (!IsPocketed || PlayerKey != playerKey || Slot != slot || playerPockets == null || !playerPockets.State.TryRelease(slot, out var _)) { PocketsPlugin.Logger.LogWarning((object)$"Could not release {((Object)this).name} from slot {slot} of player {playerKey}; ignoring the release."); return; } int key = Key; playerPockets.Valuables[slot] = null; IsPocketed = false; PlayerKey = int.MinValue; Slot = -1; Show(); if (SemiFunc.IsMasterClientOrSingleplayer()) { physGrabObject.Teleport(position, rotation); } PocketsPlugin.Logger.LogInfo((object)$"Released {((Object)this).name} (value {valuable.dollarValueCurrent:F0}) from slot {slot} of player {playerKey}"); PocketsApi.RaiseRemoved(new PocketEvent(playerKey, slot, key, valuable)); RefreshLocalSlot(playerKey, slot); PlayerAvatar instance = PlayerAvatar.instance; if (autoGrab && playerKey == PlayerKeys.Local() && (Object)(object)instance != (Object)null && !instance.deadSet) { ((MonoBehaviour)this).StartCoroutine(AutoGrab()); } } private void ComputeReleasePose(int spread, out Vector3 position, out Quaternion rotation) { //IL_003b: 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_0045: 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_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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_00f2: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if ((Object)(object)main == (Object)null) { position = ((Component)this).transform.position; rotation = ((Component)this).transform.rotation; return; } Transform transform = ((Component)main).transform; rotation = Quaternion.LookRotation(transform.forward, Vector3.up); int num = LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()) & ~LayerMask.GetMask(new string[2] { "Ignore Raycast", "CollisionCheck" }); RaycastHit val = default(RaycastHit); position = (Physics.Raycast(transform.position, transform.forward, ref val, 1.5f, num) ? (((RaycastHit)(ref val)).point + ((RaycastHit)(ref val)).normal * releaseOffset) : (transform.position + transform.forward * 1.5f)); position += transform.right * ((float)spread * 0.25f); } private IEnumerator AutoGrab() { float timer = 1.5f; while (timer > 0f && (Object)(object)physGrabObject != (Object)null && (Object)(object)PhysGrabber.instance != (Object)null) { PhysGrabber.instance.OverrideGrab(physGrabObject, 0.1f, false); if (!SemiFunc.InputUp((InputKey)10)) { timer -= Time.deltaTime; yield return null; continue; } break; } } private void Hide() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer()) { foreach (PhysGrabber item in physGrabObject.playerGrabbing.ToList()) { item.OverrideGrabRelease(((MonoBehaviourPun)this).photonView.ViewID, 0.5f); } if (!valuable.committedToExtraction) { valuable.RemoveFromDollarHaulList(); } } originalScale = ((Component)this).transform.localScale; colliders = ((Component)this).GetComponentsInChildren<Collider>(); colliderStates = colliders.Select((Collider collider) => collider.enabled).ToArray(); Bounds val = default(Bounds); ((Bounds)(ref val))..ctor(((Component)this).transform.position, Vector3.zero); Collider[] array = colliders; foreach (Collider val2 in array) { ((Bounds)(ref val)).Encapsulate(val2.bounds); val2.enabled = false; } Vector3 extents = ((Bounds)(ref val)).extents; releaseOffset = ((Vector3)(ref extents)).magnitude; ((Component)this).transform.localScale = originalScale * 0.01f; if ((Object)(object)body != (Object)null) { bodyWasKinematic = body.isKinematic; body.isKinematic = true; } physGrabObject.OverrideDeactivate(0.1f); } private void Show() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.localScale = originalScale; for (int i = 0; i < colliders.Length; i++) { if ((Object)(object)colliders[i] != (Object)null && i < colliderStates.Length) { colliders[i].enabled = colliderStates[i]; } } if ((Object)(object)body != (Object)null) { body.isKinematic = bodyWasKinematic; } physGrabObject.OverrideDeactivateReset(); } private static void RefreshLocalSlot(int playerKey, int slot) { if (playerKey == PlayerKeys.Local() && !((Object)(object)Inventory.instance == (Object)null)) { InventorySpot spotByIndex = Inventory.instance.GetSpotByIndex(slot); if ((Object)(object)spotByIndex != (Object)null) { spotByIndex.UpdateUI(); } } } } internal static class PocketReleaser { internal static void ReleaseLocalPockets() { int num = PlayerKeys.Local(); PlayerPockets playerPockets = ((num == int.MinValue) ? null : PocketsApi.Find(num)); if (playerPockets == null) { return; } int num2 = 0; for (int i = 0; i < playerPockets.Valuables.Length; i++) { ValuableObject val = playerPockets.Valuables[i]; PocketedValuable pocketedValuable = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<PocketedValuable>() : null); if ((Object)(object)pocketedValuable != (Object)null) { pocketedValuable.RequestRelease(autoGrab: false, i - 1); num2++; } } if (num2 > 0) { PocketsPlugin.Logger.LogInfo((object)$"Pockets switched off: dropping {num2} stored valuable(s)"); } } } internal sealed class PocketsRoomEvents : MonoBehaviourPunCallbacks { public override void OnJoinedRoom() { HostSettings.Publish(); } public override void OnMasterClientSwitched(Player newMasterClient) { HostSettings.Publish(); } public override void OnPlayerEnteredRoom(Player newPlayer) { if (!PhotonNetwork.IsMasterClient) { return; } HostSettings.Publish(); foreach (KeyValuePair<int, PlayerPockets> item in PocketsApi.Snapshot()) { for (int i = 0; i < item.Value.Valuables.Length; i++) { ValuableObject val = item.Value.Valuables[i]; PocketedValuable pocketedValuable = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<PocketedValuable>() : null); if ((Object)(object)pocketedValuable != (Object)null) { pocketedValuable.SendStateTo(newPlayer, item.Key, i); } } } } public override void OnPlayerLeftRoom(Player otherPlayer) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient) { return; } foreach (KeyValuePair<int, PlayerPockets> item in PocketsApi.Snapshot()) { PlayerAvatar val = PlayerKeys.Resolve(item.Key); if (!((Object)(object)val == (Object)null) && val.photonView.Owner != null && val.photonView.Owner.ActorNumber != otherPlayer.ActorNumber) { continue; } for (int i = 0; i < item.Value.Valuables.Length; i++) { ValuableObject val2 = item.Value.Valuables[i]; if ((Object)(object)val2 != (Object)null) { PocketsApi.TryRemove(item.Key, i, ((Component)val2).transform.position); } } } } } internal static class PocketSync { internal static bool IsSizeAccepted(ValuableObject valuable) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected I4, but got Unknown if (SizePolicy.TryFromGameVolume((int)valuable.volumeType, out var size)) { return SizePolicy.Accepts(size, ConfigurationController.MaxValuableSize); } return false; } internal static bool CanRelease(PocketedValuable pocketed, int slot, int playerKey, Vector3 position, PlayerAvatar? avatar, float maxDistanceFromPlayer, out string reason) { //IL_0054: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_0088: 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) if ((Object)(object)avatar == (Object)null) { reason = "unknown player"; return false; } if (avatar.isDisabled || avatar.deadSet) { reason = "the player is dead or disabled"; return false; } if (!pocketed.IsPocketed || pocketed.PlayerKey != playerKey || pocketed.Slot != slot) { reason = "the valuable is not in that player's slot"; return false; } if (float.IsNaN(position.x) || float.IsNaN(position.y) || float.IsNaN(position.z) || float.IsInfinity(position.x) || float.IsInfinity(position.y) || float.IsInfinity(position.z) || Vector3.Distance(position, ((Component)avatar).transform.position) > maxDistanceFromPlayer) { reason = "the drop position is invalid or too far from the player"; return false; } reason = string.Empty; return true; } internal static bool CanStore(PocketedValuable pocketed, int slot, int playerKey, out string reason) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) ValuableObject valuable = pocketed.Valuable; if (!ConfigurationController.IsEnabled) { reason = "the mod is disabled"; return false; } if (!SemiFunc.RunIsLevel()) { reason = "not inside a level"; return false; } PlayerAvatar val = PlayerKeys.Resolve(playerKey); if ((Object)(object)val == (Object)null) { reason = "unknown player"; return false; } if (val.isDisabled || val.deadSet) { reason = "the player is dead or disabled"; return false; } if (!PocketState.IsValidSlot(slot)) { reason = $"invalid slot {slot}"; return false; } if (pocketed.IsPocketed) { reason = "the valuable is already pocketed"; return false; } if (valuable.committedToExtraction) { reason = "the valuable is committed to an extraction"; return false; } if (!IsSizeAccepted(valuable)) { reason = $"size {valuable.volumeType} is over the limit {ConfigurationController.MaxValuableSize}"; return false; } PlayerPockets playerPockets = PocketsApi.Find(playerKey); if (playerPockets != null && playerPockets.State.IsOccupied(slot)) { reason = $"slot {slot} is already occupied"; return false; } PhysGrabObject physGrabObject = pocketed.PhysGrabObject; if ((Object)(object)val.physGrabber == (Object)null || !physGrabObject.playerGrabbing.Contains(val.physGrabber) || physGrabObject.playerGrabbing.Count != 1) { reason = "the valuable is not held only by the requesting player"; return false; } reason = string.Empty; return true; } } } namespace Pockets.Domain { public enum PocketSize { Tiny, Small, Medium, Big, Wide, Tall, VeryTall } internal sealed class PocketState { internal const int SlotCount = 3; internal const int NoValuable = int.MinValue; private readonly int[] slots = new int[3]; internal int OccupiedCount { get { int num = 0; int[] array = slots; for (int i = 0; i < array.Length; i++) { if (array[i] != int.MinValue) { num++; } } return num; } } internal PocketState() { Clear(); } internal static bool IsValidSlot(int slot) { if (slot >= 0) { return slot < 3; } return false; } internal bool IsOccupied(int slot) { if (IsValidSlot(slot)) { return slots[slot] != int.MinValue; } return false; } internal int Get(int slot) { if (!IsValidSlot(slot)) { return int.MinValue; } return slots[slot]; } internal int FindSlot(int valuableKey) { if (valuableKey == int.MinValue) { return -1; } for (int i = 0; i < 3; i++) { if (slots[i] == valuableKey) { return i; } } return -1; } internal bool TryStore(int slot, int valuableKey) { if (!IsValidSlot(slot) || valuableKey == int.MinValue || slots[slot] != int.MinValue || FindSlot(valuableKey) != -1) { return false; } slots[slot] = valuableKey; return true; } internal bool TryRelease(int slot, out int valuableKey) { if (!IsOccupied(slot)) { valuableKey = int.MinValue; return false; } valuableKey = slots[slot]; slots[slot] = int.MinValue; return true; } internal int FirstFreeSlot() { for (int i = 0; i < 3; i++) { if (slots[i] == int.MinValue) { return i; } } return -1; } internal void Clear() { for (int i = 0; i < 3; i++) { slots[i] = int.MinValue; } } internal int[] Snapshot() { return (int[])slots.Clone(); } } internal static class SizePolicy { internal static bool Accepts(PocketSize valuable, PocketSize maximum) { return valuable <= maximum; } internal static bool TryFromGameVolume(int gameVolume, out PocketSize size) { if (gameVolume < 0 || gameVolume > 6) { size = PocketSize.Tiny; return false; } size = (PocketSize)gameVolume; return true; } } } namespace Pockets.Api { public sealed class PlayerDyingEventArgs { public int PlayerKey { get; } public bool Cancel { get; set; } public PlayerDyingEventArgs(int playerKey) { PlayerKey = playerKey; } } internal sealed class PlayerPockets { internal PocketState State { get; } = new PocketState(); internal ValuableObject?[] Valuables { get; } = (ValuableObject?[])(object)new ValuableObject[3]; internal void Clear() { State.Clear(); for (int i = 0; i < Valuables.Length; i++) { Valuables[i] = null; } } } public readonly struct PocketEvent { public int PlayerKey { get; } public int Slot { get; } public int ValuableKey { get; } public ValuableObject? Valuable { get; } public PocketEvent(int playerKey, int slot, int valuableKey, ValuableObject? valuable) { PlayerKey = playerKey; Slot = slot; ValuableKey = valuableKey; Valuable = valuable; } } public static class PocketsApi { private static readonly Dictionary<int, PlayerPockets> Players = new Dictionary<int, PlayerPockets>(); private static readonly HashSet<string> SlotValueRequirements = new HashSet<string>(); internal static bool SlotValueRequired => SlotValueRequirements.Count > 0; public static event Action<PocketEvent>? Stored; public static event Action<PocketEvent>? Removed; public static event Action<PlayerDyingEventArgs>? PlayerDying; public static void RequireSlotValue(string requesterId) { if (!string.IsNullOrEmpty(requesterId)) { SlotValueRequirements.Add(requesterId); } } public static void ReleaseSlotValueRequirement(string requesterId) { SlotValueRequirements.Remove(requesterId); } internal static List<KeyValuePair<int, PlayerPockets>> Snapshot() { return new List<KeyValuePair<int, PlayerPockets>>(Players); } public static IReadOnlyList<ValuableObject?> GetStored(int playerKey) { if (!Players.TryGetValue(playerKey, out PlayerPockets value)) { return (IReadOnlyList<ValuableObject?>)(object)new ValuableObject[3]; } return (IReadOnlyList<ValuableObject>)value.Valuables.Clone(); } public static bool IsPocketed(ValuableObject valuable) { foreach (PlayerPockets value in Players.Values) { ValuableObject[] valuables = value.Valuables; for (int i = 0; i < valuables.Length; i++) { if ((Object)(object)valuables[i] == (Object)(object)valuable) { return true; } } } return false; } public static bool TryRemove(int playerKey, int slot, Vector3? at = null) { //IL_006a: 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_006f: 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_0074: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer()) { return false; } PlayerPockets playerPockets = Find(playerKey); if (playerPockets == null || !PocketState.IsValidSlot(slot) || !playerPockets.State.IsOccupied(slot) || (Object)(object)playerPockets.Valuables[slot] == (Object)null) { return false; } PocketedValuable component = ((Component)playerPockets.Valuables[slot]).GetComponent<PocketedValuable>(); if ((Object)(object)component == (Object)null) { return false; } Vector3 position = (Vector3)(((??)at) ?? DefaultDropPosition(playerKey, component)); component.BroadcastRelease(slot, playerKey, position, Quaternion.identity, autoGrab: false); return true; } private static Vector3 DefaultDropPosition(int playerKey, PocketedValuable pocketed) { //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_0031: 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_0016: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar val = PlayerKeys.Resolve(playerKey); if (!((Object)(object)val != (Object)null)) { return ((Component)pocketed).transform.position; } return ((Component)val).transform.position + Vector3.up * 0.5f; } internal static PlayerPockets GetOrCreate(int playerKey) { if (!Players.TryGetValue(playerKey, out PlayerPockets value)) { value = new PlayerPockets(); Players[playerKey] = value; } return value; } internal static PlayerPockets? Find(int playerKey) { if (!Players.TryGetValue(playerKey, out PlayerPockets value)) { return null; } return value; } internal static void Forget(int playerKey, int slot) { PlayerPockets playerPockets = Find(playerKey); if (playerPockets != null && playerPockets.State.TryRelease(slot, out var _)) { playerPockets.Valuables[slot] = null; } } internal static void ClearAll() { foreach (PlayerPockets value in Players.Values) { value.Clear(); } Players.Clear(); } internal static void RaiseStored(PocketEvent pocketEvent) { Raise(PocketsApi.Stored, pocketEvent, "Stored"); } internal static void RaiseRemoved(PocketEvent pocketEvent) { Raise(PocketsApi.Removed, pocketEvent, "Removed"); } internal static bool RaisePlayerDying(int playerKey) { PlayerDyingEventArgs e = new PlayerDyingEventArgs(playerKey); Raise(PocketsApi.PlayerDying, e, "PlayerDying"); return e.Cancel; } private static void Raise<T>(Action<T>? handlers, T argument, string eventName) { if (handlers == null) { return; } Delegate[] invocationList = handlers.GetInvocationList(); foreach (Delegate obj in invocationList) { try { ((Action<T>)obj)(argument); } catch (Exception arg) { PocketsPlugin.Logger.LogError((object)$"A subscriber of PocketsApi.{eventName} threw: {arg}"); } } } } }