Decompiled source of PickMore v0.7.0

PickMore.dll

Decompiled 3 weeks ago
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 <CustomIntermediateEndPick>d__1 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public GameObject pickedCard;

			public CardChoice cc;

			public int theInt;

			public int pickId;

			private Vector3 <startPos>5__2;

			private Vector3 <endPos>5__3;

			private AnimationCurve <curve>5__4;

			private float <speed>5__5;

			private float <c>5__6;

			private List<GameObject> <spawnedCards>5__7;

			private AnimationCurve <softCurve>5__8;

			private Vector3 <slotStart>5__9;

			private Vector3 <slotEnd>5__10;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CustomIntermediateEndPick>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<curve>5__4 = null;
				<spawnedCards>5__7 = null;
				<softCurve>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;
					<startPos>5__2 = pickedCard.transform.position;
					<endPos>5__3 = ((Component)CardChoiceVisuals.instance).transform.position;
					<curve>5__4 = ((cc.curve != null) ? cc.curve : AnimationCurve.EaseInOut(0f, 0f, 1f, 1f));
					<speed>5__5 = 4f;
					try
					{
						if (speedField != null)
						{
							<speed>5__5 = (float)speedField.GetValue(cc);
						}
					}
					catch
					{
					}
					<c>5__6 = 0f;
					goto IL_0178;
				case 1:
					<>1__state = -1;
					goto IL_0178;
				case 2:
					<>1__state = -1;
					<softCurve>5__8 = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
					<slotStart>5__9 = ((Component)cc).transform.GetChild(theInt).position;
					<slotEnd>5__10 = <startPos>5__2;
					<c>5__6 = 0f;
					break;
				case 3:
					{
						<>1__state = -1;
						break;
					}
					IL_0178:
					if (<c>5__6 < 1f)
					{
						if ((Object)(object)CardChoiceVisuals.instance != (Object)null)
						{
							CardChoiceVisuals.instance.framesToSnap = 1;
						}
						Vector3 position = Vector3.LerpUnclamped(<startPos>5__2, <endPos>5__3, <curve>5__4.Evaluate(<c>5__6));
						if ((Object)(object)pickedCard != (Object)null)
						{
							pickedCard.transform.position = position;
						}
						((Component)cc).transform.GetChild(theInt).position = position;
						<c>5__6 += Time.deltaTime * <speed>5__5;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					try
					{
						Vector3 val = <startPos>5__2 - <endPos>5__3;
						GamefeelManager.GameFeel(Vector2.op_Implicit(((Vector3)(ref val)).normalized * 2f));
					}
					catch
					{
					}
					if ((Object)(object)pickedCard != (Object)null)
					{
						CardVisuals componentInChildren = pickedCard.GetComponentInChildren<CardVisuals>();
						if ((Object)(object)componentInChildren != (Object)null)
						{
							componentInChildren.Leave();
						}
					}
					<spawnedCards>5__7 = null;
					try
					{
						<spawnedCards>5__7 = (List<GameObject>)spawnedCardsField.GetValue(cc);
					}
					catch
					{
					}
					if (<spawnedCards>5__7 != null && (Object)(object)pickedCard != (Object)null)
					{
						<spawnedCards>5__7.Remove(pickedCard);
					}
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 2;
					return true;
				}
				if (<c>5__6 < 1f)
				{
					Vector3 position2 = Vector3.LerpUnclamped(<slotStart>5__9, <slotEnd>5__10, <softCurve>5__8.Evaluate(<c>5__6));
					((Component)cc).transform.GetChild(theInt).position = position2;
					<c>5__6 += Time.deltaTime * <speed>5__5 * 1.5f;
					<>2__current = null;
					<>1__state = 3;
					return true;
				}
				try
				{
					SoundPlayerStatic.Instance.PlayPlayerBallDisappear();
				}
				catch
				{
				}
				((Component)cc).transform.GetChild(theInt).position = <startPos>5__2;
				if ((Object)(object)pickedCard != (Object)null)
				{
					try
					{
						Object.Destroy((Object)(object)pickedCard);
					}
					catch
					{
					}
				}
				if (<spawnedCards>5__7 != null && <spawnedCards>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(<CustomIntermediateEndPick>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 <CustomIntermediateEndPick>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 <Start>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<int> 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<int>("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<GameObject>)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<float> 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);
		}
	}
}