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 GambleTime { get; private set; } public static FieldRef GambleInProgress { get; private set; } public static FieldRef ReelSpinning { get; private set; } public static FieldRef ReelObjs { get; private set; } public static FieldRef 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(type, "gambleTime"); GambleInProgress = AccessTools.FieldRefAccess(type, "gambleInProgress"); ReelSpinning = AccessTools.FieldRefAccess(type, "reelSpinning"); ReelObjs = AccessTools.FieldRefAccess(type, "reelObjs"); AudioSourceRef = AccessTools.FieldRefAccess(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 Enabled; public static ConfigEntry SpinSpeedMultiplier; public static ConfigEntry ReelVisualSpeedMultiplier; public static ConfigEntry StopMusicOnFinish; public static void Bind(ConfigFile config) { Enabled = config.Bind("General", "Enabled", true, "Master switch for the mod."); SpinSpeedMultiplier = config.Bind("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("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("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)."); } } }