Decompiled source of LethalCasinoTweaks v0.1.0

LethalCasinoTweaks.dll

Decompiled 3 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LethalCasinoTweaks.Config;
using LethalCasinoTweaks.Modules.Casino;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LethalCasinoTweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Faster slot machines for Lethal Casino: shorter spins and quicker payouts. Everyone in the lobby installs it.")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+16c075f6f4cfce48c86c16a0d303d7979c7c76f1")]
[assembly: AssemblyProduct("LethalCasinoTweaks")]
[assembly: AssemblyTitle("LethalCasinoTweaks")]
[assembly: AssemblyVersion("0.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 LethalCasinoTweaks
{
	[BepInPlugin("Haaylo.LethalCasinoTweaks", "LethalCasinoTweaks", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				ModConfig.Bind(((BaseUnityPlugin)this).Config);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Config binding failed; using defaults where possible: {arg}");
			}
			try
			{
				_harmony = new Harmony("Haaylo.LethalCasinoTweaks");
				_harmony.PatchAll(typeof(Plugin).Assembly);
				if (CasinoBridge.TryResolve(Log))
				{
					SlotMachinePatches.Apply(_harmony);
				}
				int num = 0;
				foreach (MethodBase patchedMethod in _harmony.GetPatchedMethods())
				{
					_ = patchedMethod;
					num++;
				}
				Log.LogInfo((object)string.Format("{0} {1}: {2} game methods patched.", "LethalCasinoTweaks", "0.1.0", num));
			}
			catch (Exception arg2)
			{
				Log.LogError((object)$"Harmony patching failed; the mod will stay idle: {arg2}");
			}
		}
	}
	public static class PluginInfo
	{
		public const string GUID = "Haaylo.LethalCasinoTweaks";

		public const string NAME = "LethalCasinoTweaks";

		public const string VERSION = "0.1.0";
	}
}
namespace LethalCasinoTweaks.Modules.Casino
{
	internal static class CasinoBridge
	{
		public const string CasinoGuid = "mrgrm7.LethalCasino";

		public static bool Available { get; private set; }

		public static MethodInfo UpdateMethod { get; private set; }

		public static MethodInfo DoneGambleMethod { get; private set; }

		public static FieldRef<object, float> GambleTime { get; private set; }

		public static FieldRef<object, bool> GambleInProgress { get; private set; }

		public static FieldRef<object, bool[]> ReelSpinning { get; private set; }

		public static FieldRef<object, GameObject[]> ReelObjs { get; private set; }

		public static FieldRef<object, AudioSource> AudioSourceRef { get; private set; }

		public static bool TryResolve(ManualLogSource log)
		{
			Available = false;
			try
			{
				if (!Chainloader.PluginInfos.TryGetValue("mrgrm7.LethalCasino", out var value) || (Object)(object)value.Instance == (Object)null)
				{
					log.LogInfo((object)"Lethal Casino present: False (nothing to patch).");
					return false;
				}
				Type type = ((object)value.Instance).GetType().Assembly.GetType("LethalCasino.Custom.SlotMachine");
				if (type == null)
				{
					return Missing(log, "type LethalCasino.Custom.SlotMachine");
				}
				UpdateMethod = AccessTools.Method(type, "Update", (Type[])null, (Type[])null);
				if (UpdateMethod == null)
				{
					return Missing(log, "SlotMachine.Update()");
				}
				DoneGambleMethod = AccessTools.Method(type, "DoneGamble", (Type[])null, (Type[])null);
				if (DoneGambleMethod == null)
				{
					return Missing(log, "SlotMachine.DoneGamble()");
				}
				GambleTime = AccessTools.FieldRefAccess<float>(type, "gambleTime");
				GambleInProgress = AccessTools.FieldRefAccess<bool>(type, "gambleInProgress");
				ReelSpinning = AccessTools.FieldRefAccess<bool[]>(type, "reelSpinning");
				ReelObjs = AccessTools.FieldRefAccess<GameObject[]>(type, "reelObjs");
				AudioSourceRef = AccessTools.FieldRefAccess<AudioSource>(type, "audioSource");
				Available = true;
				log.LogInfo((object)$"Lethal Casino present: True ({value.Metadata.Version}); SlotMachine bound.");
				return true;
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("Lethal Casino present but its SlotMachine could not be bound (mod updated?); tweaks disabled: " + ex.Message));
				return false;
			}
		}

		private static bool Missing(ManualLogSource log, string what)
		{
			log.LogWarning((object)("Lethal Casino present but " + what + " was not found (mod updated?); tweaks disabled."));
			return false;
		}
	}
	internal static class SlotMachinePatches
	{
		private const float VanillaReelDegreesPerSecond = 2500f;

		private static bool _faulted;

		private static bool Active
		{
			get
			{
				if (!_faulted)
				{
					return ModConfig.Enabled.Value;
				}
				return false;
			}
		}

		public static int Apply(Harmony harmony)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0041: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			if (!CasinoBridge.Available)
			{
				return 0;
			}
			harmony.Patch((MethodBase)CasinoBridge.UpdateMethod, new HarmonyMethod(typeof(SlotMachinePatches), "UpdatePrefix", (Type[])null), new HarmonyMethod(typeof(SlotMachinePatches), "UpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)CasinoBridge.DoneGambleMethod, new HarmonyMethod(typeof(SlotMachinePatches), "DoneGamblePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			return 2;
		}

		private static void UpdatePrefix(object __instance)
		{
			if (!Active)
			{
				return;
			}
			try
			{
				if (CasinoBridge.GambleInProgress.Invoke(__instance))
				{
					float num = Mathf.Clamp(ModConfig.SpinSpeedMultiplier.Value, 1f, 10f);
					if (!(num <= 1f))
					{
						CasinoBridge.GambleTime.Invoke(__instance) += Time.deltaTime * (num - 1f);
					}
				}
			}
			catch (Exception e)
			{
				Fault(e);
			}
		}

		private static void UpdatePostfix(object __instance)
		{
			if (!Active)
			{
				return;
			}
			try
			{
				float num = Mathf.Clamp(ModConfig.ReelVisualSpeedMultiplier.Value, 1f, 10f);
				if (num <= 1f || !CasinoBridge.GambleInProgress.Invoke(__instance))
				{
					return;
				}
				bool[] array = CasinoBridge.ReelSpinning.Invoke(__instance);
				GameObject[] array2 = CasinoBridge.ReelObjs.Invoke(__instance);
				if (array == null || array2 == null)
				{
					return;
				}
				float num2 = 2500f * (num - 1f) * Time.deltaTime;
				int num3 = Mathf.Min(array.Length, array2.Length);
				for (int i = 0; i < num3; i++)
				{
					if (array[i] && (Object)(object)array2[i] != (Object)null)
					{
						array2[i].transform.Rotate(num2, 0f, 0f);
					}
				}
			}
			catch (Exception e)
			{
				Fault(e);
			}
		}

		private static void DoneGamblePrefix(object __instance)
		{
			if (!Active || !ModConfig.StopMusicOnFinish.Value)
			{
				return;
			}
			try
			{
				AudioSource val = CasinoBridge.AudioSourceRef.Invoke(__instance);
				if ((Object)(object)val != (Object)null)
				{
					val.Stop();
				}
			}
			catch (Exception e)
			{
				Fault(e);
			}
		}

		private static void Fault(Exception e)
		{
			if (!_faulted)
			{
				_faulted = true;
				Plugin.Log.LogError((object)$"Slot machine tweak failed; disabling for this session: {e}");
			}
		}
	}
}
namespace LethalCasinoTweaks.Config
{
	public static class ModConfig
	{
		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<float> SpinSpeedMultiplier;

		public static ConfigEntry<float> ReelVisualSpeedMultiplier;

		public static ConfigEntry<bool> StopMusicOnFinish;

		public static void Bind(ConfigFile config)
		{
			Enabled = config.Bind<bool>("General", "Enabled", true, "Master switch for the mod.");
			SpinSpeedMultiplier = config.Bind<float>("Slots", "SpinSpeedMultiplier", 2f, "How many times faster a slot machine spin runs (1 = vanilla 5 seconds, 2 = 2.5 seconds). Everyone in the lobby should use the same value.");
			ReelVisualSpeedMultiplier = config.Bind<float>("Slots", "ReelVisualSpeedMultiplier", 1.5f, "How much faster the reels visually whirl while spinning (1 = vanilla). Cosmetic only; the result is never affected.");
			StopMusicOnFinish = config.Bind<bool>("Slots", "StopMusicOnFinish", true, "Cut the spin music the moment the outcome plays (the vanilla clip is about 5 seconds long and would overlap the jackpot/lose sound on fast spins).");
		}
	}
}