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 LethalCasinoSpawner v0.2.1
Tomatobird.LethalCasinoSpawner.dll
Decompiled 3 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using LethalCasino.Custom; using LethalCasino.patches; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("mrgrm7.LethalCasino")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Tomatobird.LethalCasinoSpawner")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.1.0")] [assembly: AssemblyInformationalVersion("0.2.1+b335565ab9c8f35e5ced31aef10d1f0e341d1b50")] [assembly: AssemblyProduct("LethalCasinoSpawner")] [assembly: AssemblyTitle("Tomatobird.LethalCasinoSpawner")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.1.0")] [module: UnverifiableCode] [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 LethalCasinoSpawner { [BepInPlugin("Tomatobird.LethalCasinoSpawner", "LethalCasinoSpawner", "0.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class LethalCasinoSpawner : BaseUnityPlugin { public static ConfigEntry<bool> terminalEnabled = null; public static ConfigEntry<bool> configEnabled = null; public static List<ConfigEntry<string>> moonConfigurations = new List<ConfigEntry<string>>(); internal static Scene latestScene; public static LethalCasinoSpawner Instance { get; private set; } = null; internal static ManualLogSource Logger { get; private set; } = null; internal static Harmony? Harmony { get; set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; terminalEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Terminal Commands", true, "Whether the terminal commands for spawning/despawning casino should be enabled. Host only."); configEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Per Moon Configs", true, "Whether the per-moon configuration for spawning casino assets should be enabled. Host only."); Patch(); SceneManager.sceneLoaded += OnSceneLoad; Logger.LogInfo((object)"Tomatobird.LethalCasinoSpawner v0.2.1 has loaded!"); } internal static void Patch() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("Tomatobird.LethalCasinoSpawner"); } Logger.LogDebug((object)"Patching..."); Harmony.PatchAll(); Logger.LogDebug((object)"Finished patching!"); } internal static void OnSceneLoad(Scene scene, LoadSceneMode mode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) latestScene = scene; } internal static void Unpatch() { Logger.LogDebug((object)"Unpatching..."); Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Logger.LogDebug((object)"Finished unpatching!"); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "Tomatobird.LethalCasinoSpawner"; public const string PLUGIN_NAME = "LethalCasinoSpawner"; public const string PLUGIN_VERSION = "0.2.1"; } } namespace LethalCasinoSpawner.Patches { [HarmonyPatch(typeof(CasinoBuilding))] internal class CasinoBuildingPatcher { [HarmonyPatch("Awake")] [HarmonyTranspiler] internal static IEnumerable<CodeInstruction> Awake_Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(SceneManager), "GetSceneByName", new Type[1] { typeof(string) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(CasinoBuildingPatcher), "GetLastLoadedScene", (Type[])null, (Type[])null); return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"CompanyBuilding", (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo, (string)null) }).ThrowIfNotMatch("Couldn't find GetSceneByName pattern in CasinoBuilding.Awake()", Array.Empty<CodeMatch>()).RemoveInstruction() .SetInstruction(new CodeInstruction(OpCodes.Call, (object)methodInfo2)) .InstructionEnumeration(); } internal static Scene GetLastLoadedScene() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) LethalCasinoSpawner.Logger.LogDebug((object)("GetLastLoadedScene was called using patched CasinoBuilding.Awake(). Last loaded scene name: " + ((Scene)(ref LethalCasinoSpawner.latestScene)).name)); return LethalCasinoSpawner.latestScene; } [HarmonyPatch("Update")] [HarmonyPrefix] internal static bool Update_Prefix(CasinoBuilding __instance) { if ((Object)(object)__instance.fog == (Object)null) { return false; } return true; } } [HarmonyPatch] internal class CasinoSpawner { private static readonly string[] validObjects = new string[7] { "CasinoBuilding", "SlotMachine", "Roulette", "Jukebox", "ATM", "Blackjack", "TheWheel" }; private static readonly (string Key, string Prefab, Vector3 LocalPosition, Quaternion LocalRotation)[] casinoBuildingData = new(string, string, Vector3, Quaternion)[9] { ("CasinoBuilding", "CasinoBuilding", new Vector3(-16.8f, -1.6f, 8.3227f), Quaternion.Euler(0f, 180f, 0f)), ("SlotMachine1", "SlotMachine", new Vector3(-20.5584f, -2.5291f, 4.9645f), Quaternion.Euler(0f, 0f, 0f)), ("SlotMachine2", "SlotMachine", new Vector3(-23.6093f, -2.5291f, 4.9645f), Quaternion.Euler(0f, 0f, 0f)), ("SlotMachine3", "SlotMachine", new Vector3(-26.6712f, -2.5291f, 4.9645f), Quaternion.Euler(0f, 0f, 0f)), ("Roulette", "Roulette", new Vector3(-26.9403f, -2.5291f, 11.2909f), Quaternion.Euler(0f, 90f, 0f)), ("Jukebox", "Jukebox", new Vector3(-16.5368f, -0.3655f, 5.31f), Quaternion.Euler(0f, 0f, 0f)), ("ATM", "ATM", new Vector3(-8.5513f, -1.6819f, 5.0336f), Quaternion.Euler(0f, 0f, 0f)), ("Blackjack", "Blackjack", new Vector3(-20.9403f, -2.5291f, 11.2909f), Quaternion.Euler(0f, -90f, 0f)), ("TheWheel", "TheWheel", new Vector3(-23.9859f, -2.518f, 18.2677f), Quaternion.Euler(0f, 180f, 0f)) }; [HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")] [HarmonyPostfix] private static void ParsePlayerSentence_Postfix(Terminal __instance, ref TerminalNode __result) { if (!NetworkManager.Singleton.IsServer || !LethalCasinoSpawner.terminalEnabled.Value) { return; } string text = __instance.screenText.text; int textAdded = __instance.textAdded; int length = text.Length; int num = length - textAdded; string[] array = text.Substring(num, length - num).Split(" "); if (array.Length == 0) { return; } string text2 = array[0]; if (text2.Trim().ToLowerInvariant() != "casino") { return; } if (array.Length == 1) { __result = ScriptableObject.CreateInstance<TerminalNode>(); __result.displayText = "Usage:\ncasino spawn [x y z] [y] Spawns the casino (at position and y-rotation if specified)\n\ncasino (objectname) [x y z] [y] - Spawns a casino object (at position and y-rotation if specified)\nValid object names:\ncasino\nbuilding\nslotmachine/slots/slot\nroulette\njukebox\natm\nblackjack/black/bjack\nthewheel/wheel\n\ncasino despawn - Despawns all casino objects\n\n"; __result.clearPreviousText = true; return; } if (StartOfRound.Instance.inShipPhase) { __result = ScriptableObject.CreateInstance<TerminalNode>(); __result.displayText = "Cannot spawn casino in orbit."; __result.clearPreviousText = true; return; } CasinoManager casinoManager = RoundManagerPatch.CasinoManager; string text3 = array[1].Trim().ToLowerInvariant(); for (int i = 0; i < validObjects.Length; i++) { if (validObjects[i].ToLowerInvariant() == text3) { SpawnUsingTerminal(ref __result, array[1..]); return; } } switch (text3) { case "spawn": case "instantiate": case "summon": case "create": case "casino": array[1] = "casino"; SpawnUsingTerminal(ref __result, array[1..]); break; case "building": array[1] = "casinobuilding"; SpawnUsingTerminal(ref __result, array[1..]); break; case "slot": case "slots": array[1] = "slotmachine"; SpawnUsingTerminal(ref __result, array[1..]); break; case "black": case "bjack": array[1] = "blackjack"; SpawnUsingTerminal(ref __result, array[1..]); break; case "wheel": array[1] = "thewheel"; SpawnUsingTerminal(ref __result, array[1..]); break; case "despawn": case "destroy": case "delete": case "remove": if (CasinoManager.Objects.Count == 0) { __result = ScriptableObject.CreateInstance<TerminalNode>(); __result.displayText = "No casino objects to remove!\n\n"; __result.clearPreviousText = true; } else { __result = ScriptableObject.CreateInstance<TerminalNode>(); __result.displayText = "Removing all casino objects!\n\n"; __result.clearPreviousText = true; casinoManager.DespawnCasinoServerRpc(); } break; } } private static void SpawnUsingTerminal(ref TerminalNode result, string[] args) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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) if (args.Length != 1 && args.Length != 4 && args.Length != 5) { result = ScriptableObject.CreateInstance<TerminalNode>(); result.displayText = "Please provide valid command arguments!\nUsage: casino spawn [x y z] [y]\nExamples:\ncasino spawn\ncasino spawn -100 15 0.24\ncasino spawn 0 10 0 270\n\n"; result.clearPreviousText = true; return; } CasinoManager casinoManager = RoundManagerPatch.CasinoManager; casinoManager.SerializeAndSendHostConfigs(); result = ScriptableObject.CreateInstance<TerminalNode>(); result.displayText = "Spawning " + args[0] + "!\n\n"; result.clearPreviousText = true; Vector3 zero = Vector3.zero; Quaternion val = Quaternion.identity; if (args.Length >= 4) { if (float.TryParse(args[1], out var result2)) { zero.x = result2; } if (float.TryParse(args[2], out var result3)) { zero.y = result3; } if (float.TryParse(args[3], out var result4)) { zero.z = result4; } if (args.Length == 5 && float.TryParse(args[4], out var result5)) { val = Quaternion.Euler(0f, result5, 0f); } } if (args[0] == "casino") { SpawnEntireCasino((args.Length > 1) ? zero : casinoBuildingData[0].LocalPosition, val); } else { SpawnCasinoObject(args[0], zero, val); } } [HarmonyPatch(typeof(RoundManager), "LoadNewLevelWait")] [HarmonyAfter(new string[] { "mrgrm7.LethalCasino" })] [HarmonyPrefix] private static void LoadNewLevelWait_Prefix(RoundManager __instance) { if (!NetworkManager.Singleton.IsServer || !LethalCasinoSpawner.configEnabled.Value) { return; } for (int i = 0; i < LethalCasinoSpawner.moonConfigurations.Count; i++) { if (((ConfigEntryBase)LethalCasinoSpawner.moonConfigurations[i]).Definition.Key == "Moon: " + __instance.currentLevel.PlanetName) { ReadMoonConfig(LethalCasinoSpawner.moonConfigurations[i].Value); break; } } } private static void ReadMoonConfig(string s) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) string[] array = s.Split(';', StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0) { LethalCasinoSpawner.Logger.LogInfo((object)"Nothing defined in configuration. Skipping..."); return; } Vector3 val2 = default(Vector3); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(",", StringSplitOptions.RemoveEmptyEntries); if (array2.Length != 7 && array2.Length != 4) { LethalCasinoSpawner.Logger.LogError((object)("Invalid spawn definition. Please use the correct formatting as seen in the description of the configuration. Invalid configuration: " + array[i])); continue; } string text = array2[0].Trim().ToLowerInvariant(); if (!float.TryParse(array2[1], out var result)) { LethalCasinoSpawner.Logger.LogError((object)("Couldn't parse x position from " + array[i])); } if (!float.TryParse(array2[2], out var result2)) { LethalCasinoSpawner.Logger.LogError((object)("Couldn't parse y position from " + array[i])); } if (!float.TryParse(array2[3], out var result3)) { LethalCasinoSpawner.Logger.LogError((object)("Couldn't parse z position from " + array[i])); } Quaternion val = Quaternion.identity; if (array2.Length == 7) { if (!float.TryParse(array2[4], out var result4)) { LethalCasinoSpawner.Logger.LogError((object)("Couldn't parse x rotation from " + array[i])); } if (!float.TryParse(array2[5], out var result5)) { LethalCasinoSpawner.Logger.LogError((object)("Couldn't parse y rotation from " + array[i])); } if (!float.TryParse(array2[6], out var result6)) { LethalCasinoSpawner.Logger.LogError((object)("Couldn't parse z rotation from " + array[i])); } val = Quaternion.Euler(result4, result5, result6); } ((Vector3)(ref val2))..ctor(result, result2, result3); if (text == "casino") { SpawnEntireCasino(val2, val); } else { SpawnCasinoObject(text, val2, val); } } } private static void SpawnCasinoObject(string objectName, Vector3 objectPosition, Quaternion objectRotation) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) bool flag = false; for (int i = 0; i < validObjects.Length; i++) { if (objectName.Trim().ToLowerInvariant() != validObjects[i].ToLowerInvariant()) { continue; } flag = true; for (int j = 0; j < 9999; j++) { if (!CasinoManager.Objects.ContainsKey($"{validObjects[i]}{j}")) { CasinoManager.Objects.Add($"{validObjects[i]}{j}", CasinoManager.Spawn(validObjects[i], objectPosition, objectRotation)); break; } } LethalCasinoSpawner.Logger.LogInfo((object)$"{validObjects[i]} spawned at {objectPosition} with rotation {objectRotation}"); } if (!flag) { LethalCasinoSpawner.Logger.LogError((object)("'" + objectName + "' did not match any available valid object name. Please provide a valid object name. You can find them in the description of any moon configuration entry.")); } } private static void SpawnEntireCasino(Vector3 offsetPosition, Quaternion offsetRotation) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) Vector3 item = casinoBuildingData[0].LocalPosition; (string, string, Vector3, Quaternion)[] array = casinoBuildingData; for (int i = 0; i < array.Length; i++) { (string, string, Vector3, Quaternion) tuple = array[i]; string item2 = tuple.Item1; string item3 = tuple.Item2; Vector3 item4 = tuple.Item3; Quaternion item5 = tuple.Item4; Vector3 val = item4 - item; Vector3 val2 = offsetPosition + offsetRotation * val; Quaternion val3 = offsetRotation * item5; LethalCasinoSpawner.Logger.LogDebug((object)$"Prefab: {item3}, centeredLocalPosition: {val}, worldPosition: {val2}, worldRotation: {((Quaternion)(ref val3)).eulerAngles}"); for (int j = 0; j < 9999; j++) { if (!CasinoManager.Objects.ContainsKey($"{item2}{j}")) { CasinoManager.Objects.Add($"{item2}{j}", CasinoManager.Spawn(item3, val2, val3)); break; } } } LethalCasinoSpawner.Logger.LogInfo((object)$"Casino spawned at position {offsetPosition} with rotation {offsetRotation}"); } [HarmonyPatch(typeof(RoundManager), "DespawnPropsAtEndOfRound")] [HarmonyAfter(new string[] { "mrgrm7.LethalCasino" })] [HarmonyPostfix] private static void DespawnPropsAtEndOfRound_Postfix(RoundManager __instance) { if (__instance.currentLevel.levelID != 3 && NetworkManager.Singleton.IsServer && CasinoManager.Objects.Count > 0) { LethalCasinoSpawner.Logger.LogInfo((object)"Despawning casino objects"); RoundManagerPatch.CasinoManager.DespawnCasinoServerRpc(); } } } [HarmonyPatch(typeof(StartOfRound))] internal class MoonConfigGenerator { [HarmonyPatch("Start")] [HarmonyPostfix] internal static void GenerateMoonConfigs(StartOfRound __instance) { LethalCasinoSpawner.Logger.LogDebug((object)"Generating configurations for each moon."); SelectableLevel[] levels = __instance.levels; for (int i = 0; i < levels.Length; i++) { LethalCasinoSpawner.moonConfigurations.Add(((BaseUnityPlugin)LethalCasinoSpawner.Instance).Config.Bind<string>("Spawning", "Moon: " + levels[i].PlanetName, "", "What type of casino object to spawn and where? Valid objects: Casino, CasinoBuilding, SlotMachine, Roulette, Jukebox, ATM, Blackjack, TheWheel. Provide 3d position and, optionally, rotation for each object. Example configuration: 'SlotMachine,25.5,10,10;Roulette,31.1,10,11.5,0,180,0;ATM,30,9.5,8'")); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }