Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of Risk of Multiprinting v1.2.0
de.mavodeli.risk_of_multiprinting.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using EntityStates; using EntityStates.Duplicator; using EntityStates.Scrapper; using Grumpy; using HarmonyLib; using Microsoft.CodeAnalysis; using R2API.Networking; using R2API.Networking.Interfaces; using RoR2; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; using risk_of_multiprinting.patches.duplicating; using risk_of_multiprinting.patches.scraplimit; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("de.mavodeli.risk_of_multiprinting")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0+f78b63b80e4716904ab075952662771514c1ca0f")] [assembly: AssemblyProduct("Risk of Multiprinting")] [assembly: AssemblyTitle("de.mavodeli.risk_of_multiprinting")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace risk_of_multiprinting { [BepInPlugin("de.mavodeli.risk_of_multiprinting", "Risk of Multiprinting", "1.2.0")] [BepInProcess("Risk of Rain 2.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; private Harmony harmonyPatcher; public static InputHandler inputHandler; public static PluginInfo PInfo { get; private set; } private void Awake() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; PInfo = ((BaseUnityPlugin)this).Info; AmountSelectorAsset.Init(); Logger.LogInfo((object)"Plugin de.mavodeli.risk_of_multiprinting is loaded!"); Stage.onStageStartGlobal += delegate { Logger.LogInfo((object)"Patching scrapper duration values"); WaitToBeginScrapping.duration = 0.1f; Scrapping.duration = 0.05f; ScrappingToIdle.duration = 0.1f; }; Logger.LogInfo((object)"Patching DLLs:"); harmonyPatcher = new Harmony("de.mavodeli.risk_of_multiprinting"); Logger.LogInfo((object)"Patching Duplicating"); NetworkingAPI.RegisterMessageType<SendCustomAmountRPC>(); harmonyPatcher.CreateClassProcessor(typeof(DuplicatingPatch)).Patch(); Logger.LogInfo((object)"Patching Scrap Limit"); harmonyPatcher.CreateClassProcessor(typeof(ScrapLimitPatch)).Patch(); inputHandler = new InputHandler(); inputHandler.inputSystem = UnityInput.Current; } private void Update() { inputHandler.update(); } } public class InputHandler { public static class KeyBindings { public static KeyCode[] confirmButtons = (KeyCode[])(object)new KeyCode[1] { (KeyCode)102 }; public static KeyCode[] abortButtons; static KeyBindings() { KeyCode[] array = new KeyCode[9]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); abortButtons = (KeyCode[])(object)array; } } public IInputSystem inputSystem; private List<(Action onConfirm, Action onAbort)> activeListeners = new List<(Action, Action)>(); public void registerListener(Action onConfirm, Action onAbort) { activeListeners.Add((onConfirm, onAbort)); } public void abort() { foreach (var activeListener in activeListeners) { activeListener.onAbort(); } activeListeners.Clear(); } public void confirm() { foreach (var activeListener in activeListeners) { activeListener.onConfirm(); } activeListeners.Clear(); } public void update() { //IL_000f: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) KeyCode[] abortButtons = KeyBindings.abortButtons; foreach (KeyCode val in abortButtons) { if (inputSystem.GetKeyDown(val)) { abort(); return; } } KeyCode[] confirmButtons = KeyBindings.confirmButtons; foreach (KeyCode val2 in confirmButtons) { if (inputSystem.GetKeyDown(val2)) { confirm(); break; } } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "de.mavodeli.risk_of_multiprinting"; public const string PLUGIN_NAME = "Risk of Multiprinting"; public const string PLUGIN_VERSION = "1.2.0"; } } namespace risk_of_multiprinting.patches.scraplimit { [HarmonyPatch] public class ScrapLimitPatch { [HarmonyPatch(typeof(ScrapperController), "PreStartClient")] [HarmonyPostfix] private static void AlterScrapLimit(ScrapperController __instance) { __instance.maxItemsToScrapAtATime = 50; } } } namespace risk_of_multiprinting.patches.duplicating { public static class AmountSelectorAsset { public static AssetBundle mainBundle; public const string bundleName = "multiprintingamountselectorpanel"; public const string assetBundleFolder = "assets"; public static string AssetBundlePath => Path.Combine(Path.GetDirectoryName(Plugin.PInfo.Location), "multiprintingamountselectorpanel"); public static void Init() { mainBundle = AssetBundle.LoadFromFile(AssetBundlePath); } public static void addPlusMinusButtonListener(Transform parentTransform, string buttonName, Slider slider, int changeBy) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown Button component = ((Component)parentTransform.Find(buttonName)).gameObject.GetComponent<Button>(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { Slider obj = slider; obj.value += (float)changeBy; }); } public static Button setupInternalListeners(GameObject panel, Action<int> OnSliderValueChange) { Transform val = panel.transform.Find("Text_currentValue"); TextMeshProUGUI textComponent = ((Component)val).gameObject.GetComponent<TextMeshProUGUI>(); Slider slider = panel.GetComponentInChildren<Slider>(); ((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float value) { OnSliderValueChange((int)value); ((TMP_Text)textComponent).text = slider.value.ToString(); }); addPlusMinusButtonListener(panel.transform, "Button_Minus_5", slider, -5); addPlusMinusButtonListener(panel.transform, "Button_Minus_1", slider, -1); addPlusMinusButtonListener(panel.transform, "Button_Plus_1", slider, 1); addPlusMinusButtonListener(panel.transform, "Button_Plus_5", slider, 5); Transform val2 = panel.transform.Find("Button_Print"); return ((Component)val2).gameObject.GetComponent<Button>(); } } [HarmonyPatch] public class DuplicatingPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Action<MPEventSystem, GameObject, Interactor, GameObject, int> <>9__1_3; public static Action<MPEventSystem, GameObject> <>9__1_4; public static UnityAction <>9__1_5; internal void <ChooseCustomAmount>b__1_3(MPEventSystem eventSystem, GameObject panel, Interactor __instance, GameObject interactableObject, int chosenValue) { eventSystem.cursorOpenerCount -= 1; Object.Destroy((Object)(object)panel); if (chosenValue != 0) { if (NetworkServer.active) { Debug.Log((object)"Risk of Multiprinting: Directly calling function with modified values"); InteractorAdditions interactorAdditions = new InteractorAdditions(); interactorAdditions.PerformModifiedDuplicationInteraction(__instance, interactableObject, chosenValue); } else { Debug.Log((object)"Risk of Multiprinting: Sending RPC message to host with modified values"); NetMessageExtensions.Send((INetMessage)(object)new SendCustomAmountRPC(((Component)__instance).gameObject, interactableObject, chosenValue), (NetworkDestination)2); } } } internal void <ChooseCustomAmount>b__1_4(MPEventSystem eventSystem, GameObject panel) { eventSystem.cursorOpenerCount -= 1; Object.Destroy((Object)(object)panel); } internal void <ChooseCustomAmount>b__1_5() { Plugin.inputHandler.confirm(); } } [HarmonyPatch(typeof(Duplicating), "DropDroplet")] [HarmonyPrefix] private static bool PatchedDropDroplet(Duplicating __instance) { if (__instance.hasDroppedDroplet) { return false; } __instance.hasDroppedDroplet = true; if (NetworkServer.active) { PurchaseInteraction component = ((EntityState)__instance).GetComponent<PurchaseInteraction>(); for (int i = 0; i < component.cost; i++) { ((EntityState)__instance).GetComponent<ShopTerminalBehavior>().DropPickup(true); } component.cost = 1; } if (!Object.op_Implicit((Object)(object)__instance.muzzleTransform)) { return false; } if (Object.op_Implicit((Object)(object)__instance.bakeEffectInstance)) { if ((Object)(object)__instance._emh_bakeEffectInstance != (Object)null && __instance._emh_bakeEffectInstance.OwningPool != null) { ((GenericPool<EffectManagerHelper>)(object)__instance._emh_bakeEffectInstance.OwningPool).ReturnObject(__instance._emh_bakeEffectInstance); } else { EntityState.Destroy((Object)(object)__instance.bakeEffectInstance); } __instance._emh_bakeEffectInstance = null; __instance.bakeEffectInstance = null; } if (!Object.op_Implicit((Object)(object)Duplicating.releaseEffectPrefab)) { return false; } EffectManager.SimpleMuzzleFlash(Duplicating.releaseEffectPrefab, ((EntityState)__instance).gameObject, Duplicating.muzzleString, false); return false; } [HarmonyPatch(typeof(Interactor), "AttemptInteraction")] [HarmonyPrefix] private static bool ChooseCustomAmount(GameObject interactableObject, Interactor __instance) { //IL_01a9: 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_01b4: Expected O, but got Unknown if (!((Object)interactableObject).name.Contains("Duplicator")) { return true; } PurchaseInteraction component = interactableObject.GetComponent<PurchaseInteraction>(); if (!Object.op_Implicit((Object)(object)component)) { return true; } Debug.Log((object)"Risk of Multiprinting: Opening duplicator prompt"); LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); HUD val = HUD.instancesList.Find((HUD instance) => instance.localUserViewer == firstLocalUser); if (!Object.op_Implicit((Object)(object)val)) { Debug.Log((object)"Risk of Mutliprinting: No HUD found!"); return false; } MPEventSystem eventSystem2 = MPEventSystem.instancesList.Find((MPEventSystem instance) => instance.localUser == firstLocalUser); if (!Object.op_Implicit((Object)(object)eventSystem2)) { return false; } int chosenValue2 = 1; MPEventSystem obj = eventSystem2; obj.cursorOpenerCount += 1; GameObject val2 = AmountSelectorAsset.mainBundle.LoadAsset<GameObject>("multiprintingAmountSelectorPanel"); GameObject panel2 = Object.Instantiate<GameObject>(val2, val.mainContainer.transform); Button val3 = AmountSelectorAsset.setupInternalListeners(panel2, delegate(int newSliderValue) { chosenValue2 = newSliderValue; }); Action<MPEventSystem, GameObject, Interactor, GameObject, int> confirmDuplicating = delegate(MPEventSystem eventSystem, GameObject panel, Interactor __instance, GameObject interactableObject, int chosenValue) { eventSystem.cursorOpenerCount -= 1; Object.Destroy((Object)(object)panel); if (chosenValue != 0) { if (NetworkServer.active) { Debug.Log((object)"Risk of Multiprinting: Directly calling function with modified values"); InteractorAdditions interactorAdditions = new InteractorAdditions(); interactorAdditions.PerformModifiedDuplicationInteraction(__instance, interactableObject, chosenValue); } else { Debug.Log((object)"Risk of Multiprinting: Sending RPC message to host with modified values"); NetMessageExtensions.Send((INetMessage)(object)new SendCustomAmountRPC(((Component)__instance).gameObject, interactableObject, chosenValue), (NetworkDestination)2); } } }; Action<MPEventSystem, GameObject> abortDuplicating = delegate(MPEventSystem eventSystem, GameObject panel) { eventSystem.cursorOpenerCount -= 1; Object.Destroy((Object)(object)panel); }; ButtonClickedEvent onClick = val3.onClick; object obj2 = <>c.<>9__1_5; if (obj2 == null) { UnityAction val4 = delegate { Plugin.inputHandler.confirm(); }; <>c.<>9__1_5 = val4; obj2 = (object)val4; } ((UnityEvent)onClick).AddListener((UnityAction)obj2); Plugin.inputHandler.registerListener(delegate { confirmDuplicating(eventSystem2, panel2, __instance, interactableObject, chosenValue2); }, delegate { abortDuplicating(eventSystem2, panel2); }); return false; } } public class SendCustomAmountRPC : INetMessage, ISerializableObject { private GameObject interactorParentObject; private GameObject duplicator; private int customAmount; public SendCustomAmountRPC() { } public SendCustomAmountRPC(GameObject interactorParentObject, GameObject duplicator, int customAmount) { this.interactorParentObject = interactorParentObject; this.duplicator = duplicator; this.customAmount = customAmount; } public void Deserialize(NetworkReader reader) { interactorParentObject = reader.ReadGameObject(); duplicator = reader.ReadGameObject(); customAmount = reader.ReadInt32(); } public void OnReceived() { if (NetworkServer.active) { Interactor component = interactorParentObject.GetComponent<Interactor>(); if (!Object.op_Implicit((Object)(object)component)) { Debug.Log((object)"Risk of Multiprinting: Restoring interactor from parent object failed!"); return; } if (!Object.op_Implicit((Object)(object)duplicator)) { Debug.Log((object)"Risk of Multiprinting: transmitting duplicator object failed!"); return; } Debug.Log((object)"Risk of Multiprinting: Received RPC message for modified duplication interaction"); InteractorAdditions interactorAdditions = new InteractorAdditions(); interactorAdditions.PerformModifiedDuplicationInteraction(component, duplicator, customAmount); } } public void Serialize(NetworkWriter writer) { writer.Write(interactorParentObject); writer.Write(duplicator); writer.Write(customAmount); } } public class InteractorAdditions { [Server] public void PerformModifiedDuplicationInteraction(Interactor interactor, GameObject duplicator, int customAmount) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 if (!NetworkServer.active) { Debug.LogWarning((object)"[Server] function 'System.Void RoR2.InteractorAdditions::PerformModifiedDuplicationInteraction(UnityEngine.GameObject)' called on client"); return; } PurchaseInteraction component = duplicator.GetComponent<PurchaseInteraction>(); Interactability interactability = component.GetInteractability(interactor); if ((int)interactability == 2) { component.cost = customAmount; if (!component.CanBeAffordedByInteractor(interactor)) { component.cost = 1; return; } component.OnInteractionBegin(interactor); GlobalEventManager.instance.OnInteractionBegin(interactor, (IInteractable)(object)component, duplicator); } } } }