Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MuseumGambling v0.1.2
MuseumGambling.dll
Decompiled 13 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")] [assembly: AssemblyCompany("MuseumGambling")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.2.0")] [assembly: AssemblyInformationalVersion("0.1.2")] [assembly: AssemblyProduct("MuseumGambling")] [assembly: AssemblyTitle("MuseumGambling")] [assembly: InternalsVisibleTo("MuseumGambling.Tests")] [assembly: AssemblyVersion("0.1.2.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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; } } } namespace MuseumGambling { internal static class GrabSpot { private static readonly Dictionary<int, Vector3> _spots = new Dictionary<int, Vector3>(); internal static void Record(int viewId, Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) _spots[viewId] = position; } internal static Vector3? Consume(int viewId) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (_spots.TryGetValue(viewId, out var value)) { _spots.Remove(viewId); return value; } return null; } } internal static class Outcome { internal static bool ShouldWin(int roll, int winChancePercent) { if (winChancePercent > 0) { return roll <= winChancePercent; } return false; } } internal static class Payout { private static readonly FieldInfo? s_dollarValueOverride = typeof(ValuableObject).GetField("dollarValueOverride", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); internal static void Spawn(Vector3 position, int value) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) try { if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } GameObject surplusValuableSmall = AssetManager.instance.surplusValuableSmall; if ((Object)(object)surplusValuableSmall == (Object)null) { Plugin.Log.LogError((object)"[MuseumGambling] surplusValuableSmall prefab missing — cannot spawn payout."); return; } GameObject val = (SemiFunc.IsMultiplayer() ? PhotonNetwork.InstantiateRoomObject("Valuables/" + ((Object)surplusValuableSmall).name, position, Quaternion.identity, (byte)0, (object[])null) : Object.Instantiate<GameObject>(surplusValuableSmall, position, Quaternion.identity)); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"[MuseumGambling] Spawn returned null."); return; } ValuableObject component = val.GetComponent<ValuableObject>(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogError((object)"[MuseumGambling] Spawned object has no ValuableObject component."); return; } if (s_dollarValueOverride == null) { Plugin.Log.LogError((object)"[MuseumGambling] dollarValueOverride field not found via reflection — value not stamped."); } else { s_dollarValueOverride.SetValue(component, value); } Plugin.Log.LogInfo((object)$"[MuseumGambling] Spawned money bag worth {value} at {position}."); } catch (Exception arg) { Plugin.Log.LogError((object)$"Payout.Spawn failed: {arg}"); } } } [BepInPlugin("darkharasho.MuseumGambling", "MuseumGambling", "0.1.2")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<int> WinChancePercent; internal static ConfigEntry<int> PayoutValue; private void Awake() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Global kill-switch. When false, the Museum Head behaves vanilla (no gambling)."); WinChancePercent = ((BaseUnityPlugin)this).Config.Bind<int>("General", "WinChancePercent", 5, new ConfigDescription("Percent chance (whole number, 0–100) that a click pays out instead of dealing damage.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); PayoutValue = ((BaseUnityPlugin)this).Config.Bind<int>("General", "PayoutValue", 50000, new ConfigDescription("Dollar value stamped on the spawned money-bag valuable on a win.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000000), Array.Empty<object>())); new Harmony("darkharasho.MuseumGambling").PatchAll(); Log.LogInfo((object)"MuseumGambling v0.1.2 loaded."); } } internal static class WinBroadcast { internal const byte EventCode = 199; private static readonly Dictionary<int, bool> _pendingDamage = new Dictionary<int, bool>(); private static readonly HashSet<int> _pendingEffects = new HashSet<int>(); private static bool _registered; internal static void Register() { if (!_registered) { PhotonNetwork.NetworkingClient.EventReceived += OnEventReceived; _registered = true; } } internal static void Send(int viewId, bool win) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) Apply(viewId, win); if (PhotonNetwork.InRoom) { object[] array = new object[2] { viewId, win }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; PhotonNetwork.RaiseEvent((byte)199, (object)array, val, SendOptions.SendReliable); } } internal static bool ConsumePendingResult(int viewId) { if (_pendingDamage.TryGetValue(viewId, out var value)) { _pendingDamage.Remove(viewId); return value; } return false; } internal static bool ConsumePendingEffect(int viewId) { return _pendingEffects.Remove(viewId); } private static void OnEventReceived(EventData ev) { if (ev.Code == 199 && ev.CustomData is object[] array && array.Length >= 2) { int viewId = (int)array[0]; bool win = (bool)array[1]; Apply(viewId, win); } } private static void Apply(int viewId, bool win) { _pendingDamage[viewId] = win; if (win) { _pendingEffects.Add(viewId); } } } internal static class WinSound { private static Sound? _sound; internal static void Play(Vector3 position) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) try { Sound val = ResolveSound(); if (val == null) { Plugin.Log.LogWarning((object)"[MuseumGambling] Could not initialize win jingle."); } else { val.Play(position, 1f, 1f, 1f, 1f); } } catch (Exception arg) { Plugin.Log.LogError((object)$"WinSound.Play failed: {arg}"); } } private static Sound? ResolveSound() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (_sound != null) { return _sound; } AudioClip val = LoadEmbeddedClip(); if ((Object)(object)val == (Object)null) { return null; } Sound val2 = new Sound(); val2.Sounds = (AudioClip[])(object)new AudioClip[1] { val }; val2.Type = (AudioType)1; val2.Volume = 0.7f; val2.VolumeRandom = 0f; val2.Pitch = 1f; val2.PitchRandom = 0f; val2.SpatialBlend = 0.7f; val2.Doppler = 0f; val2.ReverbMix = 1f; val2.FalloffMultiplier = 2f; val2.OffscreenVolume = 1f; val2.OffscreenFalloff = 1f; _sound = val2; return _sound; } private static AudioClip? LoadEmbeddedClip() { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MuseumGambling.assets.winjingle.wav"); if (stream == null) { Plugin.Log.LogError((object)"[MuseumGambling] Embedded winjingle.wav resource not found."); return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); return WavLoader.Load(memoryStream.ToArray(), "MuseumGambling.WinJingle"); } } internal static class WavLoader { internal static AudioClip? Load(byte[] data, string name) { if (data.Length < 44) { return null; } if (data[0] != 82 || data[1] != 73 || data[2] != 70 || data[3] != 70) { return null; } if (data[8] != 87 || data[9] != 65 || data[10] != 86 || data[11] != 69) { return null; } int num = BitConverter.ToInt16(data, 22); int num2 = BitConverter.ToInt32(data, 24); if (BitConverter.ToInt16(data, 34) != 16) { return null; } int i = 12; int num3 = -1; int num4 = 0; int num5; for (; i < data.Length - 8; i += 8 + num5) { string @string = Encoding.ASCII.GetString(data, i, 4); num5 = BitConverter.ToInt32(data, i + 4); if (@string == "data") { num3 = i + 8; num4 = num5; break; } } if (num3 < 0) { return null; } int num6 = num4 / 2; int num7 = num6 / num; float[] array = new float[num6]; for (int j = 0; j < num6; j++) { short num8 = BitConverter.ToInt16(data, num3 + j * 2); array[j] = (float)num8 / 32768f; } AudioClip obj = AudioClip.Create(name, num7, num, num2, false); obj.SetData(array, 0); return obj; } } public static class PluginInfo { public const string PLUGIN_GUID = "darkharasho.MuseumGambling"; public const string PLUGIN_NAME = "MuseumGambling"; public const string PLUGIN_VERSION = "0.1.2"; } } namespace MuseumGambling.Patches { [HarmonyPatch(typeof(HurtCollider), "PlayerHurt")] internal static class HurtCollider_PlayerHurt_Prefix { private static bool Prefix(HurtCollider __instance) { try { MuseumPropMoneyHead componentInParent = ((Component)__instance).GetComponentInParent<MuseumPropMoneyHead>(); if ((Object)(object)componentInParent == (Object)null) { return true; } PhotonView component = ((Component)componentInParent).GetComponent<PhotonView>(); int num = ((component != null) ? component.ViewID : 0); if (WinBroadcast.ConsumePendingResult(num)) { Plugin.Log.LogInfo((object)$"[MuseumGambling] Damage suppressed for view {num}."); return false; } return true; } catch (Exception arg) { Plugin.Log.LogError((object)$"HurtCollider.PlayerHurt prefix failed: {arg}"); return true; } } } [HarmonyPatch(typeof(MuseumPropMoneyHead), "DragInPlayerStart")] internal static class MuseumPropMoneyHead_DragInPlayerStart_Postfix { private static readonly FieldInfo? PlayerToDragInField = AccessTools.Field(typeof(MuseumPropMoneyHead), "playerToDragIn"); private static void Postfix(MuseumPropMoneyHead __instance) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) try { WinBroadcast.Register(); if (!(PlayerToDragInField == null)) { object? value = PlayerToDragInField.GetValue(__instance); PlayerAvatar val = (PlayerAvatar)((value is PlayerAvatar) ? value : null); if (val != null) { PhotonView component = ((Component)__instance).GetComponent<PhotonView>(); GrabSpot.Record((component != null) ? component.ViewID : 0, ((Component)val).transform.position); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"DragInPlayerStart postfix failed: {arg}"); } } } [HarmonyPatch(typeof(MuseumPropMoneyHead), "StateSetRPC")] internal static class MuseumPropMoneyHead_StateSetRPC_Postfix { private static void Postfix(MuseumPropMoneyHead __instance, int _newState) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Invalid comparison between Unknown and I4 //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) try { WinBroadcast.Register(); State val = (State)_newState; PhotonView component = ((Component)__instance).GetComponent<PhotonView>(); int num = ((component != null) ? component.ViewID : 0); if ((int)val == 2) { if (Plugin.Enabled.Value && (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient)) { int num2 = Random.Range(1, 101); int value = Plugin.WinChancePercent.Value; bool flag = Outcome.ShouldWin(num2, value); Plugin.Log.LogInfo((object)$"[MuseumGambling] viewId={num} roll={num2} chance={value} win={flag}"); WinBroadcast.Send(num, flag); } } else if ((int)val == 3 && WinBroadcast.ConsumePendingEffect(num)) { Plugin.Log.LogInfo((object)$"[MuseumGambling] Effects firing for view {num}."); if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) { Payout.Spawn((Vector3)(((??)GrabSpot.Consume(num)) ?? ((Component)__instance).transform.position) + Vector3.up * 0.5f, Plugin.PayoutValue.Value); } WinSound.Play(((Component)__instance).transform.position); FlashEyesGreen(__instance); } } catch (Exception arg) { Plugin.Log.LogError((object)$"MuseumPropMoneyHead.StateSetRPC postfix failed: {arg}"); } } private static void FlashEyesGreen(MuseumPropMoneyHead head) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)head.eye1Light != (Object)null) { head.eye1Light.color = Color.green; } if ((Object)(object)head.eye2Light != (Object)null) { head.eye2Light.color = Color.green; } } } }