Decompiled source of ScratchCash v0.0.0

Games/Cash/Cash.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using FMODUnity;
using Microsoft.CodeAnalysis;
using Mirror;
using MoreMountains.Feedbacks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;

[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("Cash")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Cash")]
[assembly: AssemblyTitle("Cash")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CashMod
{
	[BepInPlugin("com.kit2soin.cash", "Cash", "0.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class CashPlugin : BaseUnityPlugin
	{
		private void Awake()
		{
		}
	}
}
namespace MoreGameBase
{
	public class Cash : GameBase
	{
		private class ResultData
		{
			public int multiplicator;

			public double probability;

			public int[] splitPossibilities;
		}

		private class BaseNumberData
		{
			public int number;

			public int multiplicator;
		}

		public InteractableEventTrigger playButton;

		private int numberRowCount = 4;

		private int numberColCount = 5;

		private int baseNumberCount = 20;

		private int winNumberCount = 5;

		private float waitBeforeResetTimeWin = 2.5f;

		private float waitBeforeResetTimeLoose = 1.5f;

		private ResultData[] resultData = new ResultData[10]
		{
			new ResultData
			{
				multiplicator = 100000,
				probability = 6.360306598579585E-07,
				splitPossibilities = new int[1] { 1 }
			},
			new ResultData
			{
				multiplicator = 20000,
				probability = 3.1801532992897924E-07,
				splitPossibilities = new int[1] { 1 }
			},
			new ResultData
			{
				multiplicator = 2000,
				probability = 7.95038324822448E-07,
				splitPossibilities = new int[2] { 1, 2 }
			},
			new ResultData
			{
				multiplicator = 1000,
				probability = 1.590076649644896E-06,
				splitPossibilities = new int[1] { 1 }
			},
			new ResultData
			{
				multiplicator = 100,
				probability = 0.00047702299489346884,
				splitPossibilities = new int[1] { 1 }
			},
			new ResultData
			{
				multiplicator = 20,
				probability = 0.02830336436367915,
				splitPossibilities = new int[2] { 1, 2 }
			},
			new ResultData
			{
				multiplicator = 10,
				probability = 0.02830336436367915,
				splitPossibilities = new int[2] { 1, 2 }
			},
			new ResultData
			{
				multiplicator = 4,
				probability = 0.10176490557727336,
				splitPossibilities = new int[4] { 1, 2, 3, 4 }
			},
			new ResultData
			{
				multiplicator = 2,
				probability = 0.45317438927143483,
				splitPossibilities = new int[2] { 1, 2 }
			},
			new ResultData
			{
				multiplicator = 1,
				probability = 0.3879736142680758,
				splitPossibilities = new int[1] { 1 }
			}
		};

		private static Random RNG = new Random();

		private Coroutine? drawing;

		public GameObject ticketPrefab;

		public Transform ticketPoint;

		public Camera playerCam;

		public Camera resultCam;

		public Transform hitTarget;

		public SpriteMask mask;

		public int spriteWidth = 498;

		public int spriteHeight = 328;

		public int spritePixelPerUnit = 100;

		public float brushSize = 25f;

		public float finishedThreshold = 0.98f;

		private Transform? ticket;

		private Vector2 extents;

		private int totalPixels;

		private Color[] pixels;

		private Texture2D texture;

		private int totalVisiblePixels;

		private Color transparent = new Color(0f, 0f, 0f, 0f);

		private Color nonTransparent = new Color(1f, 1f, 1f, 1f);

		private Action onCardFullyRevealed;

		public Color goldenColor = new Color(1f, 0.68f, 0f, 1f);

		public EventReference winSFX;

		public EventReference loseSFX;

		public EventReference tieSFX;

		private ParticleSystem winVFX;

		private ParticleSystem loseVFX;

		private ParticleSystem tieVFX;

		private void Start()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			playButton.onInteractEvent.AddListener((UnityAction<PlayerInteract>)delegate
			{
				((MMFeedbacks)((Component)((Component)playButton).transform.Find("Feedbacks/PressFB")).gameObject.GetComponent<MMF_Player>()).PlayFeedbacks();
			});
			playButton.serverOnInteractEvent.AddListener((UnityAction<PlayerInteract>)((GameBase)this).TryStartGame);
			extents = new Vector2((float)spriteWidth / (float)spritePixelPerUnit / 2f, (float)spriteHeight / (float)spritePixelPerUnit / 2f);
			totalPixels = spriteWidth * spriteHeight;
			pixels = (Color[])(object)new Color[totalPixels];
			texture = new Texture2D(spriteWidth, spriteHeight, (TextureFormat)4, false);
			ticketPoint = ((Component)this).transform.Find("Model/TicketPoint");
			winVFX = ((Component)((Component)this).transform.Find("Feedbacks/GameWinVFX")).gameObject.GetComponent<ParticleSystem>();
			loseVFX = ((Component)((Component)this).transform.Find("Feedbacks/GameLoseVFX")).gameObject.GetComponent<ParticleSystem>();
			tieVFX = ((Component)((Component)this).transform.Find("Feedbacks/GameTieVFX")).gameObject.GetComponent<ParticleSystem>();
		}

		public override void OnStartServer()
		{
			base.gameFeedbacks = ((Component)this).GetComponent<CasinoGameFeedbacks>();
			((GameBase)this).OnStartServer();
		}

		public override void TryStartGame(PlayerInteract playerInteract)
		{
			if (!base.isPlaying)
			{
				((GameBase)this).TryStartGame(playerInteract);
			}
		}

		protected override void StartGame()
		{
			if (!NetworkServer.active)
			{
				return;
			}
			((GameBase)this).StartGame();
			ResultData result = GetRandomWin();
			bool win = result != null;
			int[] randomisedNumbers = GetRandomisedNumbers();
			int[] array = new int[winNumberCount];
			int[] matchingWinNumbers = null;
			BaseNumberData[] array2 = new BaseNumberData[baseNumberCount];
			int num = 0;
			if (win)
			{
				int[] randomWinSplit = GetRandomWinSplit(result);
				matchingWinNumbers = new int[randomWinSplit.Length];
				num = randomWinSplit.Length;
				for (int i = 0; i < randomWinSplit.Length; i++)
				{
					array[i] = randomisedNumbers[i];
					matchingWinNumbers[i] = array[i];
					array2[i] = new BaseNumberData
					{
						number = randomisedNumbers[i],
						multiplicator = randomWinSplit[i]
					};
				}
			}
			for (int j = num; j < winNumberCount; j++)
			{
				array[j] = randomisedNumbers[j];
			}
			for (int k = 0; k < baseNumberCount - num; k++)
			{
				ResultData resultData = this.resultData[Random.Range(0, this.resultData.Length)];
				array2[num + k] = new BaseNumberData
				{
					number = randomisedNumbers[winNumberCount + k],
					multiplicator = resultData.multiplicator
				};
			}
			array2 = ShuffleList(array2);
			array = ShuffleList(array);
			onCardFullyRevealed = delegate
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				double num2 = (win ? ((double)result.multiplicator) : 0.0);
				((GameBase)this).Payout(num2, (ChangeType)1, (Dictionary<string, object>)null, (BigNumber?)((GameBase)this).currentBet);
				BroadcastPlayGameResultFeedback(num2, matchingWinNumbers);
				((MonoBehaviour)this).StartCoroutine(WaitBeforeResetCoroutine(win ? waitBeforeResetTimeWin : waitBeforeResetTimeLoose, BroadcastResetGame));
			};
			BroadcastNewTicket(array2, array);
		}

		private T[] ShuffleList<T>(T[] list)
		{
			return list.OrderBy((T _) => RNG.Next()).ToArray();
		}

		private ResultData GetRandomWin()
		{
			double num = RNG.NextDouble();
			if (num > 0.262041875)
			{
				return null;
			}
			for (int i = 0; i < resultData.Length - 1; i++)
			{
				if (num <= resultData[i].probability)
				{
					return resultData[i];
				}
			}
			return resultData[resultData.Length - 1];
		}

		private int[] GetRandomisedNumbers()
		{
			int[] list = new int[40]
			{
				1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
				11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
				21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
				31, 32, 33, 34, 35, 36, 37, 38, 39, 40
			};
			return ShuffleList(list);
		}

		private int[] GetRandomWinSplit(ResultData result)
		{
			int num = result.splitPossibilities[Random.Range(0, result.splitPossibilities.Length)];
			int[] array = new int[num];
			int num2 = result.multiplicator;
			for (int num3 = num; num3 > 0; num3--)
			{
				array[num3 - 1] = num2 / num3;
				num2 -= array[num3 - 1];
			}
			return array;
		}

		private IEnumerator WaitBeforeResetCoroutine(float duration, Action callback)
		{
			yield return (object)new WaitForSeconds(duration);
			callback();
			yield return null;
		}

		private void NewTicket()
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			playerCam = ((Component)((Component)base.interactingPlayer).transform.Find("Model/PlayerHead/CameraController/Camera(Clone)")).gameObject.GetComponent<Camera>();
			ticket = Object.Instantiate<GameObject>(ticketPrefab).transform;
			ticket.SetParent(ticketPoint, false);
			InteractableEventTrigger component = ((Component)ticket).gameObject.GetComponent<InteractableEventTrigger>();
			component.onHoldEvent.AddListener((UnityAction<PlayerInteract>)OnHoldToScratch);
			component.onHoldExitEvent.AddListener((UnityAction<PlayerInteract>)OnExitHoldToScratch);
			component.onHoverExitEvent.AddListener((UnityAction<PlayerInteract>)OnExitHoldToScratch);
			resultCam = ((Component)ticket.Find("ResultCam")).gameObject.GetComponent<Camera>();
			totalVisiblePixels = CountVisiblePixels(ScreenAsSprite(resultCam));
			hitTarget = ticket;
			mask = ((Component)ticket.Find("SpriteMask")).gameObject.GetComponent<SpriteMask>();
			mask.sprite = Sprite.Create(texture, new Rect(0f, 0f, (float)spriteWidth, (float)spriteHeight), new Vector2(0.5f, 0.5f), (float)spritePixelPerUnit);
		}

		private void OnHoldToScratch(PlayerInteract pi)
		{
			if (((Component)pi).GetComponent<PlayerProfile>().steamId == base.interactingPlayer.steamId)
			{
				StartScratch();
			}
		}

		private void OnExitHoldToScratch(PlayerInteract pi)
		{
			if (((Component)pi).GetComponent<PlayerProfile>().steamId == base.interactingPlayer.steamId)
			{
				StopScratch();
			}
		}

		private unsafe void InitTicket(BaseNumberData[] baseNumbers, int[] winNumbers)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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)
			ResetScratchTexture();
			Transform val = ((Component)this).transform.Find("Model/TicketPoint/TicketPrefab(Clone)");
			for (int i = 0; i < numberRowCount; i++)
			{
				Transform val2 = val.Find($"Numbers/BaseNumbers/Row{i}");
				for (int j = 0; j < numberColCount; j++)
				{
					Transform val3 = val2.Find($"{j}");
					BaseNumberData baseNumberData = baseNumbers[i * numberColCount + j];
					BigNumber val4 = ((GameBase)this).currentBet;
					if (((GameBase)this).currentBet == ((GameBase)this).MinBet)
					{
						val4 = BigNumber.Parse(((object)(*(BigNumber*)(&val4))/*cast due to .constrained prefix*/).ToString());
					}
					BigNumber val5 = baseNumberData.multiplicator * val4;
					((TMP_Text)((Component)val3.Find("Number")).gameObject.GetComponent<TextMeshPro>()).text = baseNumberData.number.ToString();
					((TMP_Text)((Component)val3.Find("Multiplicator")).gameObject.GetComponent<TextMeshPro>()).text = "x" + NumberToSpacedString(baseNumberData.multiplicator);
					((TMP_Text)((Component)val3.Find("Gain")).gameObject.GetComponent<TextMeshPro>()).text = $"${val5}";
				}
			}
			Transform val6 = val.Find("Numbers/WinNumbers");
			for (int k = 0; k < winNumberCount; k++)
			{
				((TMP_Text)((Component)val6.Find($"{k}")).gameObject.GetComponent<TextMeshPro>()).text = winNumbers[k].ToString();
			}
		}

		private string NumberToSpacedString(int n)
		{
			string text = n.ToString();
			if (text.Length > 3)
			{
				text = text.Insert(text.Length - 3, " ");
			}
			return text;
		}

		private void RemoveTicket()
		{
			Transform? obj = ticket;
			if (obj != null)
			{
				obj.SetParent((Transform)null);
			}
			Transform? obj2 = ticket;
			Object.Destroy((Object)(object)((obj2 != null) ? ((Component)obj2).gameObject : null));
			ticket = null;
		}

		private void StartScratch()
		{
			StopScratch();
			drawing = ((MonoBehaviour)this).StartCoroutine(ScratchRayCast());
		}

		private void StopScratch()
		{
			if (drawing != null)
			{
				((MonoBehaviour)this).StopCoroutine(drawing);
				drawing = null;
				if (GetTotalScratched() >= (double)finishedThreshold)
				{
					onCardFullyRevealed?.Invoke();
				}
			}
		}

		private IEnumerator ScratchRayCast()
		{
			RaycastHit hit = default(RaycastHit);
			while (true)
			{
				Ray ray = new Ray(((Component)playerCam).transform.position, ((Component)playerCam).transform.forward);
				if (Physics.Raycast(ray, ref hit))
				{
					Vector3 localHit = hitTarget.InverseTransformPoint(((RaycastHit)(ref hit)).point);
					int x = (int)((localHit.x * -1f + extents.x) * (float)spritePixelPerUnit);
					int y = (int)((localHit.y + extents.y) * (float)spritePixelPerUnit);
					BroadcastScratch(x, y);
				}
				yield return null;
				hit = default(RaycastHit);
			}
		}

		private void Scratch(int x, int y)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			int num = (int)(brushSize / 2f);
			int num2 = x - num;
			int num3 = x + num;
			int num4 = y - num;
			int num5 = y + num;
			for (int i = num2; i <= num3; i++)
			{
				if (i < 0 || i > spriteWidth)
				{
					continue;
				}
				for (int j = num4; j <= num5; j++)
				{
					if (j >= 0 && j <= spriteHeight)
					{
						pixels[i + spriteWidth * j] = nonTransparent;
					}
				}
			}
			texture.SetPixels(pixels);
			texture.Apply(false);
		}

		private void ResetScratchTexture()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < totalPixels; i++)
			{
				pixels[i] = transparent;
			}
			texture.SetPixels(pixels);
			texture.Apply(false);
		}

		private Sprite ScreenAsSprite(Camera cam)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			RenderTexture val = new RenderTexture(Screen.width, Screen.height, 24);
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(0f, 0f, (float)Screen.width, (float)Screen.height);
			Texture2D val3 = new Texture2D(Screen.width, Screen.height, (TextureFormat)4, false);
			cam.targetTexture = val;
			cam.Render();
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = val;
			val3.ReadPixels(val2, 0, 0);
			val3.Apply();
			cam.targetTexture = null;
			RenderTexture.active = active;
			Object.Destroy((Object)(object)val);
			return Sprite.Create(val3, val2, new Vector2(0.5f, 0.5f), (float)spritePixelPerUnit);
		}

		private int CountVisiblePixels(Sprite sprite)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			Color[] array = sprite.texture.GetPixels();
			foreach (Color val in array)
			{
				if (val.a > 0f)
				{
					num++;
				}
			}
			return num;
		}

		private double GetTotalScratched()
		{
			int num = CountVisiblePixels(ScreenAsSprite(resultCam));
			return 1.0 - (double)num / (double)totalVisiblePixels;
		}

		private void PlayGameResultFeedback(double multiplier, string[]? matchingWinNumbers)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			ColorizedMatchingNumbers(matchingWinNumbers);
			if (multiplier < 1.0)
			{
				loseVFX.Play(true);
				SFXManager.SFXOneShot(winSFX, ((Component)this).transform.position);
			}
			else if (multiplier > 1.0)
			{
				winVFX.Play(true);
				SFXManager.SFXOneShot(loseSFX, ((Component)this).transform.position);
			}
			else
			{
				tieVFX.Play(true);
				SFXManager.SFXOneShot(tieSFX, ((Component)this).transform.position);
			}
		}

		private void ColorizedMatchingNumbers(string[]? matchingNumbers)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			if (matchingNumbers == null)
			{
				return;
			}
			Transform val = ((Component)this).transform.Find("Model/TicketPoint/TicketPrefab(Clone)");
			for (int i = 0; i < numberRowCount; i++)
			{
				Transform val2 = val.Find($"Numbers/BaseNumbers/Row{i}");
				for (int j = 0; j < numberColCount; j++)
				{
					Transform val3 = val2.Find($"{j}");
					TextMeshPro component = ((Component)val3.Find("Number")).gameObject.GetComponent<TextMeshPro>();
					if (matchingNumbers.Contains(((TMP_Text)component).text))
					{
						((TMP_Text)component).color = goldenColor;
						((TMP_Text)((Component)val3.Find("Multiplicator")).gameObject.GetComponent<TextMeshPro>()).color = goldenColor;
						((TMP_Text)((Component)val3.Find("Gain")).gameObject.GetComponent<TextMeshPro>()).color = goldenColor;
					}
				}
			}
			Transform val4 = val.Find("Numbers/WinNumbers");
			for (int k = 0; k < winNumberCount; k++)
			{
				TextMeshPro component2 = ((Component)val4.Find($"{k}")).gameObject.GetComponent<TextMeshPro>();
				if (matchingNumbers.Contains(((TMP_Text)component2).text))
				{
					((TMP_Text)component2).color = goldenColor;
				}
			}
		}

		private void Broadcast(string methodName, string param)
		{
			if (NetworkServer.active)
			{
				string text = "System.Void MoreGameBase.Cash::" + methodName + "(System.String)";
				int stableHashCode = Extensions.GetStableHashCode(text);
				NetworkWriterPooled val = NetworkWriterPool.Get();
				NetworkWriterExtensions.WriteString((NetworkWriter)(object)val, param);
				((NetworkBehaviour)this).SendRPCInternal(text, stableHashCode, (NetworkWriter)(object)val, 0, true);
				NetworkWriterPool.Return(val);
			}
		}

		private void BroadcastNewTicket(BaseNumberData[] baseNumbers, int[] winNumbers)
		{
			string param = string.Join(':', baseNumbers.Select((BaseNumberData x) => $"{x.number}/{x.multiplicator}").ToArray()) + ";" + string.Join(':', winNumbers);
			Broadcast("UserRpcNewTicket", param);
		}

		public void UserRpcNewTicket(string message)
		{
			if (NetworkClient.active)
			{
				string[] array = message.Split(';');
				BaseNumberData[] baseNumbers = (from x in array[0].Split(':')
					select x.Split('/') into x
					select new BaseNumberData
					{
						number = int.Parse(x[0]),
						multiplicator = int.Parse(x[1])
					}).ToArray();
				int[] winNumbers = (from x in array[1].Split(':')
					select int.Parse(x)).ToArray();
				NewTicket();
				InitTicket(baseNumbers, winNumbers);
			}
		}

		private void BroadcastResetGame()
		{
			Broadcast("UserRpcResetGame", "");
		}

		public void UserRpcResetGame(string _)
		{
			if (NetworkClient.active)
			{
				RemoveTicket();
				((GameBase)this).ResetGame();
			}
		}

		private void BroadcastScratch(int x, int y)
		{
			Broadcast("UserRpcScratch", $"{x}:{y}");
		}

		public void UserRpcScratch(string message)
		{
			if (NetworkClient.active)
			{
				string[] array = message.Split(':');
				Scratch(int.Parse(array[0]), int.Parse(array[1]));
			}
		}

		private void BroadcastPlayGameResultFeedback(double multiplier, int[]? matchingWinNumbers)
		{
			string text = $"{multiplier}";
			if (matchingWinNumbers != null)
			{
				text = text + ";" + string.Join(':', matchingWinNumbers);
			}
			Broadcast("UserRpcPlayGameResultFeedback", text);
		}

		public void UserRpcPlayGameResultFeedback(string message)
		{
			if (NetworkClient.active)
			{
				string[] matchingWinNumbers = null;
				double multiplier;
				if (message.Contains(';'))
				{
					string[] array = message.Split(';');
					multiplier = double.Parse(array[0]);
					matchingWinNumbers = array[1].Split(':');
				}
				else
				{
					multiplier = double.Parse(message);
				}
				PlayGameResultFeedback(multiplier, matchingWinNumbers);
			}
		}
	}
}