using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Photon.Pun; using SettingsUI; using SoundImplementation; using TMPro; using UnboundLib; using UnboundLib.Networking; using UnboundLib.Utils.UI; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("PickMore")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.7.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PickMore")] [assembly: AssemblyTitle("PickMore")] [assembly: AssemblyVersion("0.7.0.0")] namespace PickMore; [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.sauceproducer.rounds.pickmore", "PickMore", "0.7.0")] [BepInProcess("Rounds.exe")] public class PickMorePlugin : BaseUnityPlugin { [HarmonyPatch(typeof(CardChoice), "DoPick")] [HarmonyPriority(600)] private class CardChoiceDoPickPatch { private static void Prefix(ref int picksToSet) { int num = Mathf.Clamp(MaxPicks, 1, 30); if (num > picksToSet) { picksToSet = num; } picksMadeInSession = 0; DoneRequested = false; } } [HarmonyPatch(typeof(CardChoice), "IDoEndPick")] private class IDoEndPickPatch { [CompilerGenerated] private sealed class d__1 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public GameObject pickedCard; public CardChoice cc; public int theInt; public int pickId; private Vector3 5__2; private Vector3 5__3; private AnimationCurve 5__4; private float 5__5; private float 5__6; private List 5__7; private AnimationCurve 5__8; private Vector3 5__9; private Vector3 5__10; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__4 = null; 5__7 = null; 5__8 = null; <>1__state = -2; } private bool MoveNext() { //IL_0032: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_035a: 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_0243: Expected O, but got Unknown //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: 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_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = pickedCard.transform.position; 5__3 = ((Component)CardChoiceVisuals.instance).transform.position; 5__4 = ((cc.curve != null) ? cc.curve : AnimationCurve.EaseInOut(0f, 0f, 1f, 1f)); 5__5 = 4f; try { if (speedField != null) { 5__5 = (float)speedField.GetValue(cc); } } catch { } 5__6 = 0f; goto IL_0178; case 1: <>1__state = -1; goto IL_0178; case 2: <>1__state = -1; 5__8 = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); 5__9 = ((Component)cc).transform.GetChild(theInt).position; 5__10 = 5__2; 5__6 = 0f; break; case 3: { <>1__state = -1; break; } IL_0178: if (5__6 < 1f) { if ((Object)(object)CardChoiceVisuals.instance != (Object)null) { CardChoiceVisuals.instance.framesToSnap = 1; } Vector3 position = Vector3.LerpUnclamped(5__2, 5__3, 5__4.Evaluate(5__6)); if ((Object)(object)pickedCard != (Object)null) { pickedCard.transform.position = position; } ((Component)cc).transform.GetChild(theInt).position = position; 5__6 += Time.deltaTime * 5__5; <>2__current = null; <>1__state = 1; return true; } try { Vector3 val = 5__2 - 5__3; GamefeelManager.GameFeel(Vector2.op_Implicit(((Vector3)(ref val)).normalized * 2f)); } catch { } if ((Object)(object)pickedCard != (Object)null) { CardVisuals componentInChildren = pickedCard.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.Leave(); } } 5__7 = null; try { 5__7 = (List)spawnedCardsField.GetValue(cc); } catch { } if (5__7 != null && (Object)(object)pickedCard != (Object)null) { 5__7.Remove(pickedCard); } <>2__current = (object)new WaitForSeconds(0.25f); <>1__state = 2; return true; } if (5__6 < 1f) { Vector3 position2 = Vector3.LerpUnclamped(5__9, 5__10, 5__8.Evaluate(5__6)); ((Component)cc).transform.GetChild(theInt).position = position2; 5__6 += Time.deltaTime * 5__5 * 1.5f; <>2__current = null; <>1__state = 3; return true; } try { SoundPlayerStatic.Instance.PlayPlayerBallDisappear(); } catch { } ((Component)cc).transform.GetChild(theInt).position = 5__2; if ((Object)(object)pickedCard != (Object)null) { try { Object.Destroy((Object)(object)pickedCard); } catch { } } if (5__7 != null && 5__7.Count == 0) { Player val2 = null; try { if ((Object)(object)PlayerManager.instance != (Object)null && PlayerManager.instance.players != null && pickId >= 0 && pickId < PlayerManager.instance.players.Count) { val2 = PlayerManager.instance.players[pickId]; } } catch { } if ((Object)(object)val2 != (Object)null && (Object)(object)val2.data != (Object)null && (Object)(object)val2.data.view != (Object)null && val2.data.view.IsMine) { cc.picks = 1; if (replaceCardsMethod != null) { IEnumerator enumerator = (IEnumerator)replaceCardsMethod.Invoke(cc, new object[2] { null, false }); ((MonoBehaviour)cc).StartCoroutine(enumerator); } } } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static bool Prefix(CardChoice __instance, ref IEnumerator __result, GameObject pickedCard, int theInt, int pickId) { int num = Mathf.Clamp(MaxPicks, 1, 30); if (num <= 1) { return true; } picksMadeInSession++; if (picksMadeInSession >= num || DoneRequested) { __instance.picks = 0; return true; } __result = CustomIntermediateEndPick(__instance, pickedCard, theInt, pickId); return false; } [IteratorStateMachine(typeof(d__1))] private static IEnumerator CustomIntermediateEndPick(CardChoice cc, GameObject pickedCard, int theInt, int pickId) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0) { cc = cc, pickedCard = pickedCard, theInt = theInt, pickId = pickId }; } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__17_0; internal void b__17_0() { } } public const string ModId = "com.sauceproducer.rounds.pickmore"; public const string ModName = "PickMore"; public const string Version = "0.7.0"; public const int HardMaxPicks = 30; public static ConfigEntry MaxPicksConfig; internal static bool DoneRequested; internal static int picksMadeInSession; internal static FieldInfo spawnedCardsField; internal static FieldInfo speedField; internal static MethodInfo replaceCardsMethod; public static PickMorePlugin Instance { get; private set; } public static int MaxPicks { get { if (MaxPicksConfig != null) { return MaxPicksConfig.Value; } return 1; } } private void Awake() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) Instance = this; MaxPicksConfig = ((BaseUnityPlugin)this).Config.Bind("PickMore", "MaxPicks", 1, "Number of cards picked per round. Host's value applies in multiplayer. Range 1-" + 30 + "."); spawnedCardsField = typeof(CardChoice).GetField("spawnedCards", BindingFlags.Instance | BindingFlags.NonPublic); speedField = typeof(CardChoice).GetField("speed", BindingFlags.Instance | BindingFlags.NonPublic); replaceCardsMethod = typeof(CardChoice).GetMethod("ReplaceCards", BindingFlags.Instance | BindingFlags.NonPublic); new Harmony("com.sauceproducer.rounds.pickmore").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("[PickMore] v0.7.0 loaded. MaxPicks=" + MaxPicks)); } private void Start() { //IL_0019: 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_0024: Expected O, but got Unknown object obj = <>c.<>9__17_0; if (obj == null) { UnityAction val = delegate { }; <>c.<>9__17_0 = val; obj = (object)val; } Unbound.RegisterMenu("PickMore", (UnityAction)obj, (Action)BuildMenu, (GameObject)null, false); Unbound.RegisterHandshake("com.sauceproducer.rounds.pickmore", (Action)OnHandshakeCompleted); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[PickMore] hooks registered."); } private static void OnHandshakeCompleted() { if (PhotonNetwork.IsMasterClient) { NetworkingManager.RPC_Others(typeof(PickMorePlugin), "SyncMaxPicks", new object[1] { MaxPicks }); } } [UnboundRPC] private static void SyncMaxPicks(int hostValue) { int value = Mathf.Clamp(hostValue, 1, 30); if (MaxPicksConfig != null) { MaxPicksConfig.Value = value; } if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[PickMore] Host set MaxPicks=" + value)); } } [UnboundRPC] private static void SyncContinue() { DoneRequested = true; if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[PickMore] Continue broadcast received."); } } internal void BuildMenu(GameObject menu) { try { TextMeshProUGUI val = default(TextMeshProUGUI); MenuHandler.CreateText("PickMore", menu, ref val, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); MenuHandler.CreateText(" ", menu, ref val, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); MenuHandler.CreateText("The losing player picks N cards per round, choosing from the same set of cards. The on-screen Continue button stops picking early.", menu, ref val, 24, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); MenuHandler.CreateText(" ", menu, ref val, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); int maxPicks = MaxPicks; UnityAction val2 = delegate(float v) { try { int num = Mathf.Clamp(Mathf.RoundToInt(v), 1, 30); if (MaxPicksConfig != null) { MaxPicksConfig.Value = num; } if (PhotonNetwork.IsMasterClient && !PhotonNetwork.OfflineMode) { NetworkingManager.RPC_Others(typeof(PickMorePlugin), "SyncMaxPicks", new object[1] { num }); } } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)("[PickMore] slider onChange threw: " + ex2)); } }; Slider val3 = default(Slider); MenuHandler.CreateSlider("Cards per round", menu, 30, 1f, 30f, (float)maxPicks, val2, ref val3, true, (Color?)null, (Direction)0, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); MenuHandler.CreateText(" ", menu, ref val, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("[PickMore] BuildMenu threw: " + ex)); } } private void OnGUI() { //IL_013d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)CardChoice.instance == (Object)null || !CardChoice.instance.IsPicking || DoneRequested) { return; } int num = Mathf.Clamp(MaxPicks, 1, 30); if (num <= 1) { return; } int pickrID = CardChoice.instance.pickrID; if (pickrID < 0) { return; } Player val = null; try { if ((Object)(object)PlayerManager.instance != (Object)null && PlayerManager.instance.players != null && pickrID >= 0 && pickrID < PlayerManager.instance.players.Count) { val = PlayerManager.instance.players[pickrID]; } } catch { } if ((Object)(object)val == (Object)null || (Object)(object)val.data == (Object)null || (Object)(object)val.data.view == (Object)null || !val.data.view.IsMine) { return; } int num2 = Mathf.Clamp(picksMadeInSession + 1, 1, num); string text = "Continue (" + num2 + "/" + num + ")"; int num3 = 280; int num4 = 64; int num5 = (Screen.width - num3) / 2; int num6 = Screen.height - num4 - 30; if (GUI.Button(new Rect((float)num5, (float)num6, (float)num3, (float)num4), text)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[PickMore] Continue clicked at pick " + num2 + "/" + num)); DoneRequested = true; if (!PhotonNetwork.OfflineMode) { NetworkingManager.RPC_Others(typeof(PickMorePlugin), "SyncContinue", new object[0]); } } } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.sauceproducer.rounds.pickmore.rwfcompat", "PickMore RWF Compatibility", "0.7.0")] [BepInProcess("Rounds.exe")] internal class PickMoreRWFCompat : CompatibilityHandler { public override string MenuName => "PickMore"; public override bool HostOnly => true; public override void Start() { try { ((CompatibilityHandler)this).Start(); } catch (Exception ex) { Debug.LogError("[PickMore] RWF compat Start() threw: " + ex); } } public override void GUI(GameObject menu) { try { if ((Object)(object)PickMorePlugin.Instance != (Object)null) { PickMorePlugin.Instance.BuildMenu(menu); } else { Debug.LogError("[PickMore] RWF compat: PickMorePlugin.Instance is null"); } } catch (Exception ex) { Debug.LogError("[PickMore] RWF compat GUI() threw: " + ex); } } }