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)delegate { ((MMFeedbacks)((Component)((Component)playButton).transform.Find("Feedbacks/PressFB")).gameObject.GetComponent()).PlayFeedbacks(); }); playButton.serverOnInteractEvent.AddListener((UnityAction)((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(); loseVFX = ((Component)((Component)this).transform.Find("Feedbacks/GameLoseVFX")).gameObject.GetComponent(); tieVFX = ((Component)((Component)this).transform.Find("Feedbacks/GameTieVFX")).gameObject.GetComponent(); } public override void OnStartServer() { base.gameFeedbacks = ((Component)this).GetComponent(); ((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)null, (BigNumber?)((GameBase)this).currentBet); BroadcastPlayGameResultFeedback(num2, matchingWinNumbers); ((MonoBehaviour)this).StartCoroutine(WaitBeforeResetCoroutine(win ? waitBeforeResetTimeWin : waitBeforeResetTimeLoose, BroadcastResetGame)); }; BroadcastNewTicket(array2, array); } private T[] ShuffleList(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(); ticket = Object.Instantiate(ticketPrefab).transform; ticket.SetParent(ticketPoint, false); InteractableEventTrigger component = ((Component)ticket).gameObject.GetComponent(); component.onHoldEvent.AddListener((UnityAction)OnHoldToScratch); component.onHoldExitEvent.AddListener((UnityAction)OnExitHoldToScratch); component.onHoverExitEvent.AddListener((UnityAction)OnExitHoldToScratch); resultCam = ((Component)ticket.Find("ResultCam")).gameObject.GetComponent(); totalVisiblePixels = CountVisiblePixels(ScreenAsSprite(resultCam)); hitTarget = ticket; mask = ((Component)ticket.Find("SpriteMask")).gameObject.GetComponent(); 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().steamId == base.interactingPlayer.steamId) { StartScratch(); } } private void OnExitHoldToScratch(PlayerInteract pi) { if (((Component)pi).GetComponent().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()).text = baseNumberData.number.ToString(); ((TMP_Text)((Component)val3.Find("Multiplicator")).gameObject.GetComponent()).text = "x" + NumberToSpacedString(baseNumberData.multiplicator); ((TMP_Text)((Component)val3.Find("Gain")).gameObject.GetComponent()).text = $"${val5}"; } } Transform val6 = val.Find("Numbers/WinNumbers"); for (int k = 0; k < winNumberCount; k++) { ((TMP_Text)((Component)val6.Find($"{k}")).gameObject.GetComponent()).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(); if (matchingNumbers.Contains(((TMP_Text)component).text)) { ((TMP_Text)component).color = goldenColor; ((TMP_Text)((Component)val3.Find("Multiplicator")).gameObject.GetComponent()).color = goldenColor; ((TMP_Text)((Component)val3.Find("Gain")).gameObject.GetComponent()).color = goldenColor; } } } Transform val4 = val.Find("Numbers/WinNumbers"); for (int k = 0; k < winNumberCount; k++) { TextMeshPro component2 = ((Component)val4.Find($"{k}")).gameObject.GetComponent(); 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); } } } }