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 ScrapperPlus v1.0.4
BepInEx/plugins/ScrapperPlus/ScrapperPlus.dll
Decompiled 16 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using RoR2; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ScrapperPlus { internal sealed class HoldRepeatButton : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerUpHandler, IPointerExitHandler { private const float InitialDelay = 0.5f; private const float Interval = 0.2f; private Action step; private Func<bool> canStep; private Action onPressStart; private Action onRelease; private bool holding; private float nextStepTime; internal void Configure(Action step, Func<bool> canStep, Action onPressStart, Action onRelease) { this.step = step; this.canStep = canStep; this.onPressStart = onPressStart; this.onRelease = onRelease; } public void OnPointerDown(PointerEventData eventData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)eventData.button == 0 && CanStepNow()) { onPressStart?.Invoke(); Step(); holding = true; nextStepTime = Time.unscaledTime + 0.5f; } } public void OnPointerUp(PointerEventData eventData) { Stop(notify: true); } public void OnPointerExit(PointerEventData eventData) { Stop(notify: true); } private void Update() { if (!holding) { return; } if (!CanStepNow()) { Stop(notify: true); } else if (!(Time.unscaledTime < nextStepTime)) { Step(); nextStepTime = Time.unscaledTime + 0.2f; if (!CanStepNow()) { Stop(notify: true); } } } private void Stop(bool notify) { if (holding) { holding = false; if (notify) { onRelease?.Invoke(); } } } private bool CanStepNow() { if (canStep != null) { return canStep(); } return true; } private void Step() { step?.Invoke(); } private void OnDisable() { Stop(notify: false); } private void OnApplicationFocus(bool hasFocus) { if (!hasFocus) { Stop(notify: true); } } } internal static class LookingGlassCompat { private const string HookTypeName = "LookingGlass.CommandItemCount.CommandItemCountClass"; private const string HookMethodName = "PickupPickerPanel"; private const int MaxAttempts = 15; private const float RetryInterval = 2f; private static Harmony harmony; private static int attempts; private static float nextAttempt; internal static bool Applied { get; private set; } internal static void Initialize(Harmony instance) { harmony = instance; } internal static void Tick() { if (!Applied && harmony != null && !(Time.unscaledTime < nextAttempt)) { nextAttempt = Time.unscaledTime + 2f; if (++attempts <= 15) { TryApply(attempts == 15); } } } private static void TryApply(bool finalAttempt) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown Type type = AccessTools.TypeByName("LookingGlass.CommandItemCount.CommandItemCountClass"); if (type == null) { if (finalAttempt) { ScrapperPlusPlugin.Log.LogInfo((object)"ScrapperPlus: LookingGlass not detected, compatibility layer skipped."); } return; } MethodInfo method = type.GetMethod("PickupPickerPanel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { attempts = 15; ScrapperPlusPlugin.Log.LogWarning((object)"ScrapperPlus: LookingGlass was found but its picker hook has changed; compatibility layer skipped."); return; } try { MethodInfo method2 = typeof(LookingGlassCompat).GetMethod("Prefix", BindingFlags.Static | BindingFlags.NonPublic); harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Applied = true; ScrapperPlusPlugin.Log.LogInfo((object)"ScrapperPlus: LookingGlass compatibility layer active (Scrapper panel hooks bypassed)."); } catch (Exception ex) { attempts = 15; ScrapperPlusPlugin.Log.LogWarning((object)("ScrapperPlus: failed to install the LookingGlass compatibility layer: " + ex)); } } private static bool Prefix(object[] __args) { try { if (__args == null || __args.Length < 3) { return true; } object obj = __args[1]; PickupPickerPanel val = (PickupPickerPanel)((obj is PickupPickerPanel) ? obj : null); if (!Object.op_Implicit((Object)(object)val) || !IsScrapperPanel(val)) { return true; } if (__args[0] is Action<PickupPickerPanel, Option[]> action && __args[2] is Option[] arg) { action(val, arg); return false; } } catch (Exception ex) { ScrapperPlusPlugin.Log.LogWarning((object)("ScrapperPlus: LookingGlass bypass failed, falling back to their code: " + ex)); } return true; } private static bool IsScrapperPanel(PickupPickerPanel panel) { PickupPickerController pickerController = panel.pickerController; if (!Object.op_Implicit((Object)(object)pickerController)) { return false; } if (!Object.op_Implicit((Object)(object)((Component)pickerController).GetComponent<ScrapperController>()) && !Object.op_Implicit((Object)(object)((Component)pickerController).GetComponentInParent<ScrapperController>())) { return Object.op_Implicit((Object)(object)((Component)pickerController).GetComponentInChildren<ScrapperController>(true)); } return true; } } [BepInPlugin("ScrapperPlus", "ScrapperPlus", "1.0.4")] public sealed class ScrapperPlusPlugin : BaseUnityPlugin { public const string PluginGuid = "ScrapperPlus"; public const string PluginName = "ScrapperPlus"; public const string PluginVersion = "1.0.4"; internal const int VanillaScrapLimit = 10; internal static int CurrentCount = 1; private Harmony harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; CurrentCount = 1; harmony = new Harmony("ScrapperPlus"); try { harmony.PatchAll(); Log.LogInfo((object)("ScrapperPlus 1.0.4 loaded. Game=" + Application.version)); } catch (Exception ex) { Log.LogError((object)("ScrapperPlus patch failure: " + ex)); } LookingGlassCompat.Initialize(harmony); LookingGlassCompat.Tick(); GameObject val = new GameObject("ScrapperPlusWatcher") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); val.AddComponent<ScrapperPanelWatcher>(); } private void OnDestroy() { try { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("Harmony unpatch failed: " + ex)); } } } } internal static class ScrapperCountNetwork { private readonly struct Key : IEquatable<Key> { public readonly int PickerId; public readonly uint ParticipantId; public Key(int pickerId, uint participantId) { PickerId = pickerId; ParticipantId = participantId; } public bool Equals(Key other) { if (PickerId == other.PickerId) { return ParticipantId == other.ParticipantId; } return false; } public override bool Equals(object obj) { if (obj is Key other) { return Equals(other); } return false; } public override int GetHashCode() { return (PickerId * 397) ^ (int)ParticipantId; } } public const byte MessageId = 83; public const uint Magic = 1397771313u; public const byte ProtocolVersion = 1; private static readonly Dictionary<Key, int> Pending = new Dictionary<Key, int>(); public static bool SetPending(PickupPickerController picker, int count) { //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 (!Object.op_Implicit((Object)(object)picker)) { return false; } NetworkUIPromptController component = ((Component)picker).GetComponent<NetworkUIPromptController>(); CharacterMaster val = (Object.op_Implicit((Object)(object)component) ? component.currentParticipantMaster : null); if (!Object.op_Implicit((Object)(object)val)) { return false; } if (Pending.Count > 256) { Pending.Clear(); } int value = Mathf.Clamp(count, 1, 10); Dictionary<Key, int> pending = Pending; int instanceID = ((Object)picker).GetInstanceID(); NetworkInstanceId netId = ((NetworkBehaviour)val).netId; pending[new Key(instanceID, ((NetworkInstanceId)(ref netId)).Value)] = value; return true; } public static bool TryTakePending(PickupPickerController picker, out int count) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) count = 10; if (!Object.op_Implicit((Object)(object)picker)) { return false; } NetworkUIPromptController component = ((Component)picker).GetComponent<NetworkUIPromptController>(); CharacterMaster val = (Object.op_Implicit((Object)(object)component) ? component.currentParticipantMaster : null); if (!Object.op_Implicit((Object)(object)val)) { return false; } int instanceID = ((Object)picker).GetInstanceID(); NetworkInstanceId netId = ((NetworkBehaviour)val).netId; Key key = new Key(instanceID, ((NetworkInstanceId)(ref netId)).Value); if (!Pending.TryGetValue(key, out var value)) { return false; } Pending.Remove(key); count = Mathf.Clamp(value, 1, 10); return true; } public static void ClearPicker(PickupPickerController picker) { if (!Object.op_Implicit((Object)(object)picker)) { return; } int instanceID = ((Object)picker).GetInstanceID(); List<Key> list = null; foreach (Key key in Pending.Keys) { if (key.PickerId == instanceID) { if (list == null) { list = new List<Key>(); } list.Add(key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { Pending.Remove(list[i]); } } } public static bool Send(PickupPickerController picker, int count) { if (!Object.op_Implicit((Object)(object)picker)) { return false; } int count2 = Mathf.Clamp(count, 1, 10); bool result = false; if (NetworkServer.active) { result = SetPending(picker, count2); } if (!NetworkClient.active) { return result; } NetworkUIPromptController component = ((Component)picker).GetComponent<NetworkUIPromptController>(); if (!Object.op_Implicit((Object)(object)component) || !component.isDisplaying || !Object.op_Implicit((Object)(object)component.currentParticipantMaster)) { return result; } NetworkWriter val = component.BeginMessageToServer(); if (val == null) { return result; } WriteCount(val, count2); component.FinishMessageToServer(val); return true; } public static void WriteCount(NetworkWriter writer, int count) { writer.Write((byte)83); writer.Write(1397771313u); writer.Write((byte)1); writer.Write(Mathf.Clamp(count, 1, 10)); } public static bool TryReadCount(NetworkReader reader, out int count) { count = 10; uint num = reader.ReadUInt32(); byte b = reader.ReadByte(); int num2 = reader.ReadInt32(); if (num != 1397771313 || b != 1) { return false; } count = Mathf.Clamp(num2, 1, 10); return true; } } internal sealed class ScrapperPanelWatcher : MonoBehaviour { private const float ScanInterval = 0.1f; private float nextScan; private PickupPickerPanel attached; private void Update() { LookingGlassCompat.Tick(); if ((Object.op_Implicit((Object)(object)attached) && ((Component)attached).gameObject.activeInHierarchy) || Time.unscaledTime < nextScan) { return; } nextScan = Time.unscaledTime + 0.1f; try { attached = FindScrapperPanel(); if (Object.op_Implicit((Object)(object)attached) && !Object.op_Implicit((Object)(object)((Component)attached).GetComponent<ScrapperPlusPanel>())) { ((Component)attached).gameObject.AddComponent<ScrapperPlusPanel>().Attach(attached); } } catch (Exception ex) { ScrapperPlusPlugin.Log.LogWarning((object)("ScrapperPlus: panel scan failed: " + ex)); } } private static PickupPickerPanel FindScrapperPanel() { PickupPickerPanel[] array = Object.FindObjectsOfType<PickupPickerPanel>(); foreach (PickupPickerPanel val in array) { if (Object.op_Implicit((Object)(object)val) && ((Component)val).gameObject.activeInHierarchy && IsScrapperPicker(val.pickerController)) { return val; } } return null; } private static bool IsScrapperPicker(PickupPickerController picker) { if (!Object.op_Implicit((Object)(object)picker)) { return false; } if (!Object.op_Implicit((Object)(object)((Component)picker).GetComponent<ScrapperController>()) && !Object.op_Implicit((Object)(object)((Component)picker).GetComponentInParent<ScrapperController>())) { return Object.op_Implicit((Object)(object)((Component)picker).GetComponentInChildren<ScrapperController>(true)); } return true; } } public sealed class ScrapperPlusPanel : MonoBehaviour { private const string ControlName = "ScrapperPlusCountControl"; private const float Gap = 12f; private const float OuterBorderThickness = 1.5f; private const float BorderGap = 2.5f; private const float InnerBorderThickness = 3f; private const float TypingTimeout = 5f; private static readonly Color BorderColor = new Color(0.89f, 0.89f, 0.896f, 1f); private static readonly Color TextColor = Color.white; private static readonly Color DisabledTextColor = new Color(0.5f, 0.5f, 0.5f, 1f); private static readonly Color TypingTextColor = new Color(1f, 0.86f, 0.35f, 1f); private static readonly Color TypingZoneColor = new Color(1f, 1f, 1f, 0.16f); private static readonly Color ClearColor = new Color(0f, 0f, 0f, 0f); private PickupPickerPanel panel; private PickupPickerController picker; private RectTransform cancelRect; private RectTransform root; private Button minusButton; private Button plusButton; private Image numberZone; private TextMeshProUGUI numberText; private TextMeshProUGUI minusText; private TextMeshProUGUI plusText; private int count = 1; private int lastBuildCheckFrame; private int buildAttempts; private bool warnedNoCancel; private bool built; private bool siblingMode; private bool closing; private bool typing; private bool countSent; private bool restoreCloseOnKey; private float typingStartTime; private float nextSendAttempt; private readonly List<Behaviour> closeOnKey = new List<Behaviour>(); private readonly List<GameObject> spawned = new List<GameObject>(); private static Sprite whiteSprite; internal void Attach(PickupPickerPanel panel) { this.panel = panel; } private void Update() { if (!Object.op_Implicit((Object)(object)panel)) { return; } bool activeInHierarchy = ((Component)panel).gameObject.activeInHierarchy; picker = panel.pickerController; if (!activeInHierarchy || !IsScrapperPicker(picker)) { if (built) { Teardown(); return; } buildAttempts = 0; warnedNoCancel = false; return; } if (!built) { int num = ((buildAttempts > 300) ? 30 : 2); if (Time.frameCount - lastBuildCheckFrame < num) { return; } lastBuildCheckFrame = Time.frameCount; TryBuild(); } if (typing) { HandleTyping(); } if (!countSent && Time.unscaledTime >= nextSendAttempt) { TrySendCount(); } } private void LateUpdate() { if (restoreCloseOnKey) { ReleaseCloseOnKey(); } if (built) { PositionRoot(); } } private void OnDestroy() { Teardown(); } private void OnDisable() { if (built) { Teardown(); } } private static bool IsScrapperPicker(PickupPickerController picker) { if (!Object.op_Implicit((Object)(object)picker)) { return false; } if (!Object.op_Implicit((Object)(object)((Component)picker).GetComponent<ScrapperController>()) && !Object.op_Implicit((Object)(object)((Component)picker).GetComponentInParent<ScrapperController>())) { return Object.op_Implicit((Object)(object)((Component)picker).GetComponentInChildren<ScrapperController>(true)); } return true; } private void TryBuild() { cancelRect = FindCancel(); if (Object.op_Implicit((Object)(object)cancelRect) && Build()) { built = true; buildAttempts = 0; Refresh(); PositionRoot(); TrySendCount(); ScrapperPlusPlugin.Log.LogInfo((object)$"ScrapperPlus: control ready, count={count}"); } else { cancelRect = null; buildAttempts++; if (buildAttempts == 301 && !warnedNoCancel) { warnedNoCancel = true; ScrapperPlusPlugin.Log.LogWarning((object)"ScrapperPlus: scrapper panel is open but the control could not be built; falling back to the vanilla limit of 10."); } } } private RectTransform FindCancel() { Transform val = ((Component)panel).transform.Find("MainPanel/Juice/CancelButton"); if (Object.op_Implicit((Object)(object)val)) { return (RectTransform)(object)((val is RectTransform) ? val : null); } Transform[] componentsInChildren = ((Component)panel).GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (string.Equals(((Object)componentsInChildren[i]).name, "CancelButton", StringComparison.OrdinalIgnoreCase)) { Transform obj = componentsInChildren[i]; return (RectTransform)(object)((obj is RectTransform) ? obj : null); } } return null; } private static Sprite WhiteSprite() { //IL_002b: 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) if (!Object.op_Implicit((Object)(object)whiteSprite)) { Texture2D whiteTexture = Texture2D.whiteTexture; whiteSprite = Sprite.Create(whiteTexture, new Rect(0f, 0f, (float)((Texture)whiteTexture).width, (float)((Texture)whiteTexture).height), new Vector2(0.5f, 0.5f)); } return whiteSprite; } private bool Build() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_00b3: 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_00dd: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) closing = false; countSent = false; nextSendAttempt = 0f; GameObject val = new GameObject("ScrapperPlusCountControl", new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button) }); root = val.GetComponent<RectTransform>(); siblingMode = IsSafeToParentNextToCancel(); ((Transform)root).SetParent(siblingMode ? ((Transform)cancelRect).parent : ((Component)panel).transform, false); ((Transform)root).SetAsLastSibling(); root.anchorMin = Vector2.zero; root.anchorMax = Vector2.zero; root.pivot = new Vector2(0f, 0.5f); ((Transform)root).localScale = Vector3.one; ((Transform)root).localRotation = Quaternion.identity; root.sizeDelta = ControlSize(); root.anchoredPosition = Vector2.zero; spawned.Add(val); val.AddComponent<LayoutElement>().ignoreLayout = true; Image component = val.GetComponent<Image>(); ((Graphic)component).color = new Color(0f, 0f, 0f, 0f); ((Graphic)component).raycastTarget = true; component.sprite = WhiteSprite(); Button component2 = val.GetComponent<Button>(); ((Selectable)component2).transition = (Transition)0; ((Selectable)component2).targetGraphic = (Graphic)(object)component; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)component2).navigation = navigation; CreateBorderFrame("Outer", 0f, 1.5f); CreateBorderFrame("Inner", 4f, 3f); TextMeshProUGUI val2 = FindText(((Component)cancelRect).gameObject); if (!Object.op_Implicit((Object)(object)val2)) { Teardown(); return false; } count = Mathf.Clamp(ScrapperPlusPlugin.CurrentCount, 1, 10); CreateNumberZone(); numberText = CreateLabel((Transform)(object)root, "ScrapperPlusNumber", count.ToString(), val2, 1f / 3f, 2f / 3f); minusButton = CreateZone("ScrapperPlusMinus", "-", 0f, 1f / 3f, val2, out minusText, -1); plusButton = CreateZone("ScrapperPlusPlus", "+", 2f / 3f, 1f, val2, out plusText, 1); Canvas.ForceUpdateCanvases(); return true; } private bool IsSafeToParentNextToCancel() { Transform parent = ((Transform)cancelRect).parent; if (!Object.op_Implicit((Object)(object)parent)) { return false; } if (Object.op_Implicit((Object)(object)((Component)parent).GetComponent<RectMask2D>()) || Object.op_Implicit((Object)(object)((Component)parent).GetComponent<Mask>())) { ScrapperPlusPlugin.Log.LogInfo((object)"ScrapperPlus: cancel container is masked; using absolute positioning."); return false; } return true; } private void CreateBorderFrame(string tag, float inset, float thickness) { //IL_001f: 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_0036: 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_0064: 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_007a: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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) float num = inset + thickness; CreateBorderStrip("ScrapperPlusBorder" + tag + "Top", new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(inset, 0f - num), new Vector2(0f - inset, 0f - inset)); CreateBorderStrip("ScrapperPlusBorder" + tag + "Bottom", new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(inset, inset), new Vector2(0f - inset, num)); CreateBorderStrip("ScrapperPlusBorder" + tag + "Left", new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(inset, num), new Vector2(num, 0f - num)); CreateBorderStrip("ScrapperPlusBorder" + tag + "Right", new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(0f - num, num), new Vector2(0f - inset, 0f - num)); } private void CreateBorderStrip(string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_008d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); spawned.Add(val); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)root, false); component.anchorMin = anchorMin; component.anchorMax = anchorMax; component.offsetMin = offsetMin; component.offsetMax = offsetMax; ((Transform)component).localScale = Vector3.one; Image component2 = val.GetComponent<Image>(); component2.sprite = WhiteSprite(); ((Graphic)component2).color = BorderColor; ((Graphic)component2).raycastTarget = false; } private Vector2 ControlSize() { //IL_0023: 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_0037: 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_0017: 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) if (!Object.op_Implicit((Object)(object)cancelRect)) { return new Vector2(200f, 48f); } Rect rect = cancelRect.rect; float num = ((Rect)(ref rect)).width; rect = cancelRect.rect; float num2 = ((Rect)(ref rect)).height; if (num < 80f || num > 600f) { num = 200f; } if (num2 < 20f || num2 > 200f) { num2 = 48f; } return new Vector2(num, num2); } private static TextMeshProUGUI FindText(GameObject rootObject) { TextMeshProUGUI[] componentsInChildren = rootObject.GetComponentsInChildren<TextMeshProUGUI>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (Object.op_Implicit((Object)(object)componentsInChildren[i]) && ((TMP_Text)componentsInChildren[i]).text == "Cancel") { return componentsInChildren[i]; } } for (int j = 0; j < componentsInChildren.Length; j++) { if (Object.op_Implicit((Object)(object)componentsInChildren[j]) && string.Equals(((Object)((Component)componentsInChildren[j]).gameObject).name, "Text", StringComparison.OrdinalIgnoreCase)) { return componentsInChildren[j]; } } if (componentsInChildren.Length == 0) { return null; } return componentsInChildren[0]; } private static void PlaceLabel(RectTransform rect, float anchorMinX, float anchorMaxX) { //IL_0007: 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_0023: 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_0039: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(anchorMinX, 0f); rect.anchorMax = new Vector2(anchorMaxX, 1f); rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; ((Transform)rect).localScale = Vector3.one; } private TextMeshProUGUI CreateLabel(Transform parent, string name, string text, TextMeshProUGUI template, float anchorMinX, float anchorMaxX) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false); ((Object)val).name = name; spawned.Add(val); PlaceLabel(val.GetComponent<RectTransform>(), anchorMinX, anchorMaxX); LanguageTextMeshController[] componentsInChildren = val.GetComponentsInChildren<LanguageTextMeshController>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; Object.Destroy((Object)(object)componentsInChildren[i]); } TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>(); if (!Object.op_Implicit((Object)(object)component)) { return null; } ((TMP_Text)component).text = text; ((Graphic)component).color = TextColor; ((TMP_Text)component).alignment = (TextAlignmentOptions)514; ((Graphic)component).raycastTarget = false; ((TMP_Text)component).enableWordWrapping = false; ((TMP_Text)component).overflowMode = (TextOverflowModes)0; return component; } private void CreateNumberZone() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00a5: 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_00f9: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown GameObject val = new GameObject("ScrapperPlusNumberZone", new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button) }); spawned.Add(val); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)root, false); component.anchorMin = new Vector2(1f / 3f, 0f); component.anchorMax = new Vector2(2f / 3f, 1f); component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; ((Transform)component).localScale = Vector3.one; ((Transform)component).SetSiblingIndex(0); numberZone = val.GetComponent<Image>(); ((Graphic)numberZone).color = ClearColor; ((Graphic)numberZone).raycastTarget = true; Button component2 = val.GetComponent<Button>(); ((Selectable)component2).targetGraphic = (Graphic)(object)numberZone; ((Selectable)component2).transition = (Transition)0; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)component2).navigation = navigation; ((UnityEvent)component2.onClick).AddListener(new UnityAction(BeginTyping)); } private Button CreateZone(string name, string symbol, float anchorMinX, float anchorMaxX, TextMeshProUGUI template, out TextMeshProUGUI label, int delta) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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) //IL_00a4: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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) GameObject val = new GameObject(name, new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button) }); spawned.Add(val); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)root, false); component.anchorMin = new Vector2(anchorMinX, 0f); component.anchorMax = new Vector2(anchorMaxX, 1f); component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; ((Transform)component).localScale = Vector3.one; Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = new Color(0f, 0f, 0f, 0f); ((Graphic)component2).raycastTarget = true; Button component3 = val.GetComponent<Button>(); ((Selectable)component3).targetGraphic = (Graphic)(object)component2; ((Selectable)component3).transition = (Transition)0; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)component3).navigation = navigation; val.AddComponent<HoldRepeatButton>().Configure(delegate { Adjust(delta); }, () => (delta >= 0) ? (count < 10) : (count > 1), PlayClick, Commit); label = CreateLabel(val.transform, name + "Label", symbol, template, 0f, 1f); return component3; } private static void PlayClick() { if (Object.op_Implicit((Object)(object)RoR2Application.instance)) { Util.PlaySound("Play_UI_menuClick", ((Component)RoR2Application.instance).gameObject); } } private void Adjust(int delta) { if (typing) { EndTyping(); } int num = Mathf.Clamp(count + delta, 1, 10); if (num != count) { count = num; ScrapperPlusPlugin.CurrentCount = count; Refresh(); } } private void BeginTyping() { if (built) { if (!typing) { typing = true; PlayClick(); SuppressCloseOnKey(); } typingStartTime = Time.unscaledTime; Refresh(); } } private void EndTyping() { if (typing) { typing = false; restoreCloseOnKey = true; Refresh(); } } private void SuppressCloseOnKey() { if (Object.op_Implicit((Object)(object)panel) && closeOnKey.Count <= 0) { CollectCloseOnKey(((Component)panel).GetComponents<MonoBehaviour>()); if (closeOnKey.Count == 0) { CollectCloseOnKey(((Component)panel).GetComponentsInChildren<MonoBehaviour>(true)); } if (closeOnKey.Count == 0) { CollectCloseOnKey(((Component)panel).GetComponentsInParent<MonoBehaviour>(true)); } for (int i = 0; i < closeOnKey.Count; i++) { closeOnKey[i].enabled = false; } } } private void CollectCloseOnKey(MonoBehaviour[] behaviours) { foreach (MonoBehaviour val in behaviours) { if (Object.op_Implicit((Object)(object)val)) { Type type = ((object)val).GetType(); if (type.Name == "ClosePickupPicker" && type.Namespace != null && type.Namespace.StartsWith("LookingGlass", StringComparison.Ordinal)) { closeOnKey.Add((Behaviour)(object)val); } } } } private void ReleaseCloseOnKey() { restoreCloseOnKey = false; for (int i = 0; i < closeOnKey.Count; i++) { if (Object.op_Implicit((Object)(object)closeOnKey[i])) { closeOnKey[i].enabled = true; } } closeOnKey.Clear(); } private void HandleTyping() { if (Time.unscaledTime - typingStartTime > 5f) { EndTyping(); return; } if (Input.GetKeyDown((KeyCode)27)) { EndTyping(); return; } for (int i = 0; i <= 9; i++) { if (Input.GetKeyDown((KeyCode)(48 + i))) { ApplyTypedDigit(i); break; } } } private void ApplyTypedDigit(int digit) { int num = ((digit == 0) ? 10 : digit); typing = false; restoreCloseOnKey = true; if (num == count) { Refresh(); return; } count = num; ScrapperPlusPlugin.CurrentCount = count; Refresh(); Commit(); } private void Commit() { if (!closing) { countSent = false; TrySendCount(); } } private void TrySendCount() { if (!closing) { nextSendAttempt = Time.unscaledTime + 0.1f; if (Object.op_Implicit((Object)(object)picker) && ScrapperCountNetwork.Send(picker, count)) { countSent = true; } } } private void Refresh() { //IL_0038: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)numberText)) { ((TMP_Text)numberText).text = count.ToString(); ((Graphic)numberText).color = (typing ? TypingTextColor : TextColor); } if (Object.op_Implicit((Object)(object)numberZone)) { ((Graphic)numberZone).color = (typing ? TypingZoneColor : ClearColor); } if (Object.op_Implicit((Object)(object)minusButton)) { ((Selectable)minusButton).interactable = count > 1; } if (Object.op_Implicit((Object)(object)plusButton)) { ((Selectable)plusButton).interactable = count < 10; } if (Object.op_Implicit((Object)(object)minusText)) { ((Graphic)minusText).color = ((count > 1) ? TextColor : DisabledTextColor); } if (Object.op_Implicit((Object)(object)plusText)) { ((Graphic)plusText).color = ((count < 10) ? TextColor : DisabledTextColor); } } private void PositionRoot() { //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: 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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_007c: 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_00a2: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: 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_0206: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: 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_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0244: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)root) || !Object.op_Implicit((Object)(object)cancelRect)) { return; } Rect rect; if (siblingMode) { if ((Object)(object)((Transform)root).parent != (Object)(object)((Transform)cancelRect).parent) { ((Transform)root).SetParent(((Transform)cancelRect).parent, false); } root.anchorMin = cancelRect.anchorMin; root.anchorMax = cancelRect.anchorMax; root.pivot = cancelRect.pivot; ((Transform)root).localScale = Vector3.one; ((Transform)root).localRotation = Quaternion.identity; bool flag = !Mathf.Approximately(cancelRect.anchorMin.x, cancelRect.anchorMax.x); RectTransform obj = root; float num; if (!flag) { rect = cancelRect.rect; num = ((Rect)(ref rect)).width; } else { num = cancelRect.sizeDelta.x; } rect = cancelRect.rect; obj.sizeDelta = new Vector2(num, ((Rect)(ref rect)).height); RectTransform obj2 = root; Vector2 anchoredPosition = cancelRect.anchoredPosition; rect = cancelRect.rect; obj2.anchoredPosition = anchoredPosition + new Vector2(((Rect)(ref rect)).width + 12f, 0f); return; } Vector2 val = ControlSize(); if (Mathf.Abs(root.sizeDelta.x - val.x) > 0.5f || Mathf.Abs(root.sizeDelta.y - val.y) > 0.5f) { root.sizeDelta = val; } RectTransform obj3 = cancelRect; rect = cancelRect.rect; float xMax = ((Rect)(ref rect)).xMax; rect = cancelRect.rect; float yMin = ((Rect)(ref rect)).yMin; rect = cancelRect.rect; Vector3 val2 = ((Transform)obj3).TransformPoint(new Vector3(xMax, (yMin + ((Rect)(ref rect)).yMax) * 0.5f, 0f)); Vector3 val3 = ((Transform)cancelRect).TransformDirection(Vector3.right); if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val3 = Vector3.right; } Vector3 val4 = ((Transform)cancelRect).TransformVector(Vector3.right); float magnitude = ((Vector3)(ref val4)).magnitude; Vector3 val5 = val2 + ((Vector3)(ref val3)).normalized * (12f * magnitude); val4 = ((Transform)root).position - val5; if (((Vector3)(ref val4)).sqrMagnitude > 0.01f) { ((Transform)root).position = val5; } } private void Teardown() { closing = true; ReleaseCloseOnKey(); ScrapperCountNetwork.ClearPicker(picker); typing = false; numberZone = null; for (int i = 0; i < spawned.Count; i++) { if (Object.op_Implicit((Object)(object)spawned[i])) { Object.Destroy((Object)(object)spawned[i]); } } spawned.Clear(); root = null; cancelRect = null; numberText = null; minusText = null; plusText = null; minusButton = null; plusButton = null; built = false; countSent = false; } } } namespace ScrapperPlus.Patches { internal static class ScrapperPatchHelpers { public static bool IsScrapperPicker(PickupPickerController picker) { if (!Object.op_Implicit((Object)(object)picker)) { return false; } if (!Object.op_Implicit((Object)(object)((Component)picker).GetComponent<ScrapperController>())) { return Object.op_Implicit((Object)(object)((Component)picker).GetComponentInParent<ScrapperController>()); } return true; } } [HarmonyPatch(typeof(PickupPickerController), "HandleClientMessage")] internal static class HandleClientMessagePatch { [HarmonyPrefix] private static bool Prefix(PickupPickerController __instance, NetworkReader reader) { if (!ScrapperPatchHelpers.IsScrapperPicker(__instance)) { return true; } try { byte b = reader.ReadByte(); switch (b) { case 0: { int num = reader.ReadInt32(); __instance.SubmitChoice(num); break; } case 1: { NetworkUIPromptController component = ((Component)__instance).GetComponent<NetworkUIPromptController>(); if (Object.op_Implicit((Object)(object)component)) { component.SetParticipantMaster((CharacterMaster)null); } ScrapperCountNetwork.ClearPicker(__instance); break; } case 83: { if (ScrapperCountNetwork.TryReadCount(reader, out var count)) { ScrapperCountNetwork.SetPending(__instance, count); } break; } default: ScrapperPlusPlugin.Log.LogDebug((object)("ScrapperPlus: ignored unknown picker message id " + b)); break; } } catch (Exception ex) { ScrapperPlusPlugin.Log.LogWarning((object)("ScrapperPlus: HandleClientMessage failed: " + ex)); } return false; } } [HarmonyPatch(typeof(PickupPickerController), "HandlePickupSelected")] internal static class HandlePickupSelectedPatch { [HarmonyPostfix] private static void Postfix(PickupPickerController __instance) { if (ScrapperPatchHelpers.IsScrapperPicker(__instance)) { ScrapperCountNetwork.ClearPicker(__instance); } } } [HarmonyPatch(typeof(ScrapperController), "BeginScrapping", new Type[] { typeof(UniquePickup) })] internal static class BeginScrappingPatch { [HarmonyPrefix] private static void Prefix(ScrapperController __instance) { if (NetworkServer.active) { int count; int num = (ScrapperCountNetwork.TryTakePending(__instance.pickupPickerController, out count) ? count : 10); __instance.maxItemsToScrapAtATime = Mathf.Clamp(num, 1, 10); } } [HarmonyPostfix] private static void Postfix(ScrapperController __instance) { if (NetworkServer.active) { __instance.maxItemsToScrapAtATime = 10; } } } }