using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MenuLib; using MenuLib.MonoBehaviors; using MenuLib.Structs; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Photon.Pun; using REPOConfig; using REPOLib.Extensions; using REPOLib.Modules; using TMPro; using TwitchChatAPI; using TwitchChatAPI.Enums; using TwitchChatAPI.Objects; using UnityEngine; using UnityEngine.AI; using UnityEngine.Networking; using UnityEngine.Serialization; using UnityEngine.UI; using com.github.zehsteam.MetadataUtils.Extensions; using com.github.zehsteam.MetadataUtils.Objects; using com.github.zehsteam.PlayerDamageTracker.Modules; using com.github.zehsteam.TwitchTrolling.Dependencies; using com.github.zehsteam.TwitchTrolling.Dependencies.MenuLibMod.MonoBehaviours; using com.github.zehsteam.TwitchTrolling.Dependencies.MenuLibMod.Patches; using com.github.zehsteam.TwitchTrolling.Dependencies.REPOConfigMod; using com.github.zehsteam.TwitchTrolling.Extensions; using com.github.zehsteam.TwitchTrolling.Helpers; using com.github.zehsteam.TwitchTrolling.MEvents; using com.github.zehsteam.TwitchTrolling.MEvents.BaseEvents; using com.github.zehsteam.TwitchTrolling.Managers; using com.github.zehsteam.TwitchTrolling.MonoBehaviours; using com.github.zehsteam.TwitchTrolling.Objects; using com.github.zehsteam.TwitchTrolling.Patches; using com.github.zehsteam.TwitchTrolling.Twitch; using com.github.zehsteam.TwitchTrolling.Twitch.Commands; using com.github.zehsteam.TwitchTrolling.Twitch.Commands.Objects; using com.github.zehsteam.TwitchTrolling.Twitch.Helpers; using com.github.zehsteam.TwitchTrolling.Twitch.Objects; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("MenuLib")] [assembly: IgnoresAccessChecksTo("REPOConfig")] [assembly: IgnoresAccessChecksTo("REPOLib")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Zehs")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2026 Zehs")] [assembly: AssemblyDescription("Let Twitch chat spawn monsters and trigger events with custom bit amounts and subs. Highly configurable, easy to use, no extension or app needed.")] [assembly: AssemblyFileVersion("1.8.0.0")] [assembly: AssemblyInformationalVersion("1.8.0+b3be926623e8c892e615579b6dce64cb54bcc435")] [assembly: AssemblyProduct("TwitchTrolling")] [assembly: AssemblyTitle("com.github.zehsteam.TwitchTrolling")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.8.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 com.github.zehsteam.TwitchTrolling { internal static class Assets { public static GameObject PluginManagerPrefab { get; private set; } public static GameObject PluginHUDPrefab { get; private set; } public static GameObject EnemyNametagWorldCanvasPrefab { get; private set; } public static GameObject TruckPropsPrefab { get; private set; } public static GameObject AudioEnemySpawnPrefab { get; private set; } public static PrefabRef ModCreditsPrefabRef { get; private set; } public static EnemyConfigEntryDefaultValuesList EnemyConfigEntryDefaultValuesList { get; private set; } public static EnemySpawnSFXList EnemySpawnSFXList { get; private set; } public static MEventSFXList MEventSFXList { get; private set; } public static void Load() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = "twitchtrolling_assets"; string text2 = Path.Combine(directoryName, text); if (!File.Exists(text2)) { Logger.LogFatal("Failed to load assets. AssetBundle file could not be found at path \"" + text2 + "\". Make sure the \"" + text + "\" file is in the same folder as the mod's DLL file."); } else { AssetBundle val = AssetBundle.LoadFromFile(text2); if ((Object)(object)val == (Object)null) { Logger.LogFatal("Failed to load assets. AssetBundle is null."); } else { OnAssetBundleLoaded(val); } } } private static void OnAssetBundleLoaded(AssetBundle assetBundle) { PluginManagerPrefab = LoadAsset("PluginManager", assetBundle); PluginHUDPrefab = LoadAsset("PluginHUD", assetBundle); EnemyNametagWorldCanvasPrefab = LoadAsset("EnemyNametagWorldCanvas", assetBundle); TruckPropsPrefab = LoadAsset("TruckProps", assetBundle); AudioEnemySpawnPrefab = LoadAsset("AudioEnemySpawn", assetBundle); Utilities.FixAudioMixerGroups(AudioEnemySpawnPrefab); ModCreditsPrefabRef = NetworkPrefabs.RegisterNetworkPrefab(LoadAsset("TwitchTrolling ModCredits", assetBundle)); EnemyConfigEntryDefaultValuesList = LoadAsset("EnemyConfigEntryDefaultValuesList", assetBundle); EnemySpawnSFXList = LoadAsset("EnemySpawnSFXList", assetBundle); MEventSFXList = LoadAsset("MEventSFXList", assetBundle); } private static T LoadAsset(string name, AssetBundle assetBundle) where T : Object { if (string.IsNullOrWhiteSpace(name)) { Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" from AssetBundle. Name is null or whitespace."); return default(T); } if ((Object)(object)assetBundle == (Object)null) { Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. AssetBundle is null."); return default(T); } T val = assetBundle.LoadAsset(name); if ((Object)(object)val == (Object)null) { Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. No asset found with that type and name."); return default(T); } return val; } private static bool TryLoadAsset(string name, AssetBundle assetBundle, out T asset) where T : Object { asset = LoadAsset(name, assetBundle); return (Object)(object)asset != (Object)null; } } internal static class Logger { public static ManualLogSource ManualLogSource { get; private set; } public static void Initialize(ManualLogSource manualLogSource) { ManualLogSource = manualLogSource; } public static void LogDebug(object data) { Log((LogLevel)32, data); } public static void LogInfo(object data, bool extended = false) { Log((LogLevel)16, data, extended); } public static void LogWarning(object data, bool extended = false) { Log((LogLevel)4, data, extended); } public static void LogError(object data, bool extended = false, bool showMessage = false) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) Log((LogLevel)2, data, extended); if (showMessage) { MessageManager.Instance?.ShowMessage(data.ToString(), Color.red); } } public static void LogFatal(object data, bool extended = false) { Log((LogLevel)1, data, extended); } public static void Log(LogLevel logLevel, object data, bool extended = false) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!extended || IsExtendedLoggingEnabled()) { ManualLogSource manualLogSource = ManualLogSource; if (manualLogSource != null) { manualLogSource.Log(logLevel, data); } } } public static bool IsExtendedLoggingEnabled() { if (ConfigManager.ExtendedLogging == null) { return false; } return ConfigManager.ExtendedLogging.Value; } } internal static class Menu { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static BuilderDelegate <>9__6_0; public static BuilderDelegate <>9__6_1; public static BuilderDelegate <>9__6_2; public static Action <>9__6_3; internal void b__6_0(Transform parent) { CreateMainButtonForMainMenu(parent); } internal void b__6_1(Transform parent) { CreateMainButtonForLobbyAndEscapeMenu(parent); } internal void b__6_2(Transform parent) { CreateMainButtonForLobbyAndEscapeMenu(parent); } internal void b__6_3() { PageManager.OnPageStatusChanged -= HandlePageStatusChanged; PageManager.OnPageCreated -= HandlePageCreated; } } private static REPOPopupPage _popupPage; private static REPOLabel _pageStatusLabel; private static REPOLabel _pageUrlLabel; private static REPOButton _createPageButton; private static REPOButton _copyPageURLButton; private static REPOButton _settingsButton; public static void Initialize() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0038: 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_0043: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown object obj = <>c.<>9__6_0; if (obj == null) { BuilderDelegate val = delegate(Transform parent) { CreateMainButtonForMainMenu(parent); }; <>c.<>9__6_0 = val; obj = (object)val; } MenuAPI.AddElementToMainMenu((BuilderDelegate)obj); object obj2 = <>c.<>9__6_1; if (obj2 == null) { BuilderDelegate val2 = delegate(Transform parent) { CreateMainButtonForLobbyAndEscapeMenu(parent); }; <>c.<>9__6_1 = val2; obj2 = (object)val2; } MenuAPI.AddElementToLobbyMenu((BuilderDelegate)obj2); object obj3 = <>c.<>9__6_2; if (obj3 == null) { BuilderDelegate val3 = delegate(Transform parent) { CreateMainButtonForLobbyAndEscapeMenu(parent); }; <>c.<>9__6_2 = val3; obj3 = (object)val3; } MenuAPI.AddElementToEscapeMenu((BuilderDelegate)obj3); PageManager.OnPageStatusChanged += HandlePageStatusChanged; PageManager.OnPageCreated += HandlePageCreated; Application.quitting += delegate { PageManager.OnPageStatusChanged -= HandlePageStatusChanged; PageManager.OnPageCreated -= HandlePageCreated; }; } private static REPOButton CreateMainButtonForMainMenu(Transform parent) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) float num = 35f; float num2 = 0f; if (SpawnManagerProxy.Enabled) { num2 += 55f; } return CreateMainButton(parent, Vector2.op_Implicit(new Vector2(550f, num + num2))); } private static REPOButton CreateMainButtonForLobbyAndEscapeMenu(Transform parent) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) float num = 0f; num += 145f; if (MoreHeadProxy.Enabled) { num += 100f; } return CreateMainButton(parent, Vector2.op_Implicit(new Vector2(num, 0f))); } private static REPOButton CreateMainButton(Transform parent, Vector3 localPosition) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) return MenuAPI.CreateREPOButton("Twitch Trolling", (Action)HandleMainButtonClick, parent, Vector2.op_Implicit(localPosition)); } private static void CreateMenu() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown _popupPage = MenuAPI.CreateREPOPopupPage("Twitch Trolling", (PresetSide)0, false, true, 0f); REPOPopupPage popupPage = _popupPage; Padding maskPadding = _popupPage.maskPadding; maskPadding.top = 35f; popupPage.maskPadding = maskPadding; float xPosition = 75f; float yPosition = 270f; _popupPage.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) _pageStatusLabel = MenuAPI.CreateREPOLabel("Page Status:", parent, new Vector2(xPosition, yPosition)); ((Component)_pageStatusLabel).transform.localScale = Vector3.one * 0.7f; }); yPosition -= 40f; _popupPage.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) _pageUrlLabel = MenuAPI.CreateREPOLabel(string.Empty, parent, new Vector2(xPosition, yPosition)); ((Component)_pageUrlLabel).transform.localScale = Vector3.one * 0.5f; }); yPosition -= 60f; _popupPage.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_002d: 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) _createPageButton = MenuAPI.CreateREPOButton("Create Page", (Action)HandleCreatePageButtonClick, parent, Vector2.op_Implicit(new Vector3(xPosition, yPosition))); }); _popupPage.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_002d: 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) _copyPageURLButton = MenuAPI.CreateREPOButton("Copy Page URL", (Action)HandleCopyPageURLButtonClick, parent, Vector2.op_Implicit(new Vector3(xPosition, yPosition))); ((Component)_copyPageURLButton).gameObject.SetActive(false); }); yPosition -= 40f; _popupPage.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_002d: 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) _settingsButton = MenuAPI.CreateREPOButton("Settings", (Action)HandleSettingsButtonClick, parent, Vector2.op_Implicit(new Vector3(xPosition, yPosition))); }); yPosition = 35f; _popupPage.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) MenuAPI.CreateREPOButton("Close", (Action)HandleCloseButtonClick, parent, new Vector2(xPosition, yPosition)); }); _popupPage.OpenPage(false); HandlePageStatusChanged(); PageManager.CheckPageStatus(); PageManager.VerifyTwitchChannel(); } private static void HandleMainButtonClick() { CreateMenu(); } private static void HandleCloseButtonClick() { REPOPopupPage popupPage = _popupPage; if (popupPage != null) { popupPage.ClosePage(true); } } private static void HandleCreatePageButtonClick() { REPOButton createPageButton = _createPageButton; if (createPageButton != null) { ((Component)createPageButton).gameObject.SetActive(false); } PageManager.CreatePage(); } private static void HandleCopyPageURLButtonClick() { if (PageManager.HasPage) { GUIUtility.systemCopyBuffer = PageManager.PageURL; } } private static void HandleSettingsButtonClick() { HandleCloseButtonClick(); REPOConfigHelper.OpenSettingsMenu("TwitchTrolling"); } private static void HandlePageStatusChanged() { if ((Object)(object)_popupPage == (Object)null) { return; } bool hasPage = PageManager.HasPage; ((Component)_createPageButton).gameObject.SetActive(!hasPage); ((Component)_copyPageURLButton).gameObject.SetActive(hasPage); if (hasPage) { ((TMP_Text)_pageStatusLabel.labelTMP).text = "Page Status: ONLINE"; string text = PageManager.PageURL.Replace("?id", "\n?id"); ((TMP_Text)_pageUrlLabel.labelTMP).text = "" + text + ""; ((TMP_Text)_pageUrlLabel.labelTMP).fontStyle = (FontStyles)1; return; } ((TMP_Text)_pageStatusLabel.labelTMP).text = "Page Status: OFFLINE"; if (!PageManager.IsCreatePageEnabled(out var reason)) { string text2 = "" + reason + ""; ((TMP_Text)_pageUrlLabel.labelTMP).text = "You are unable to create a page! Reason:\n" + text2; ((Component)_createPageButton).gameObject.SetActive(false); } else { ((TMP_Text)_pageUrlLabel.labelTMP).text = "Create a page to share your prices\nwith your viewers!"; } ((TMP_Text)_pageUrlLabel.labelTMP).fontStyle = (FontStyles)17; } private static void HandlePageCreated(string pageUrl) { HandlePageStatusChanged(); } } [BepInPlugin("com.github.zehsteam.TwitchTrolling", "TwitchTrolling", "1.8.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class Plugin : BaseUnityPlugin { private readonly Harmony _harmony = new Harmony("com.github.zehsteam.TwitchTrolling"); internal static Plugin Instance { get; private set; } internal static JsonSave GlobalSave { get; private set; } internal static JsonSave LocalSave { get; private set; } private void Awake() { Instance = this; Logger.Initialize(Logger.CreateLogSource("com.github.zehsteam.TwitchTrolling")); Logger.LogInfo("TwitchTrolling has awoken!"); _harmony.PatchAll(typeof(RunManagerPatch)); _harmony.PatchAll(typeof(LevelGeneratorPatch)); _harmony.PatchAll(typeof(EnemyDirectorPatch)); _harmony.PatchAll(typeof(HUDCanvasPatch)); _harmony.PatchAll(typeof(TruckScreenTextPatch)); _harmony.PatchAll(typeof(PlayerControllerPatch)); _harmony.PatchAll(typeof(ItemDronePatch)); _harmony.PatchAll(typeof(FanTrapPatch)); _harmony.PatchAll(typeof(ItemRubberDuckPatch)); _harmony.PatchAll(typeof(EnemyDuckPatch)); _harmony.PatchAll(typeof(REPOPopupPage_Patches)); GlobalSave = new JsonSave(Utils.GetPluginPersistentDataPath(), "GlobalSave"); LocalSave = new JsonSave(Paths.ConfigPath, "TwitchTrolling_Save.json"); Assets.Load(); CoroutineRunner.Spawn(); ConfigManager.Initialize(((BaseUnityPlugin)this).Config); PluginManager.Spawn(); TwitchIntegrationManager.Initialize(); Menu.Initialize(); PageManager.Initialize(); PlayerHelper.Initialize(); TwitchSimulateCheerCommand.Register(); TwitchSimulateSubCommand.Register(); } } internal static class Utils { [CompilerGenerated] private sealed class d__5 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public TimeSpan duration; public Action action; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds((float)duration.TotalSeconds); <>1__state = 1; return true; case 1: <>1__state = -1; action?.Invoke(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static string GetPluginPersistentDataPath() { return Path.Combine(Application.persistentDataPath, "TwitchTrolling"); } public static ConfigFile CreateConfigFile(BaseUnityPlugin plugin, string path, string name = null, bool saveOnInit = false) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown BepInPlugin metadata = MetadataHelper.GetMetadata((object)plugin); if (name == null) { name = metadata.GUID; } name += ".cfg"; return new ConfigFile(Path.Combine(path, name), saveOnInit, metadata); } public static ConfigFile CreateLocalConfigFile(BaseUnityPlugin plugin, string name = null, bool saveOnInit = false) { return CreateConfigFile(plugin, Paths.ConfigPath, name, saveOnInit); } public static ConfigFile CreateGlobalConfigFile(BaseUnityPlugin plugin, string name = null, bool saveOnInit = false) { string pluginPersistentDataPath = GetPluginPersistentDataPath(); if (name == null) { name = "global"; } return CreateConfigFile(plugin, pluginPersistentDataPath, name, saveOnInit); } public static string GetTextWithReadableColor(string text, string hexColor, string backgroundHexColor = "#000000") { if (string.IsNullOrWhiteSpace(hexColor)) { hexColor = "#FFFFFF"; } if (string.IsNullOrWhiteSpace(backgroundHexColor)) { backgroundHexColor = "#000000"; } string readableColor = ColorHelper.GetReadableColor(hexColor, backgroundHexColor); return text.RichColor(readableColor); } [IteratorStateMachine(typeof(d__5))] public static IEnumerator InvokeAfterDurationCoroutine(TimeSpan duration, Action action) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__5(0) { duration = duration, action = action }; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "com.github.zehsteam.TwitchTrolling"; public const string PLUGIN_NAME = "TwitchTrolling"; public const string PLUGIN_VERSION = "1.8.0"; } } namespace com.github.zehsteam.TwitchTrolling.Twitch { internal static class TwitchCheerHandler { public static bool IsEnemySpawnEnabled { get { if (ConfigManager.Enemy_Enabled.Value) { return EnemyConfigManager.HasEnemies(); } return false; } } public static bool IsEventSpawnEnabled { get { if (MEventManager.Enabled) { return MEventManager.HasEvents(); } return false; } } public static void HandleCheer(TwitchCheerEvent cheerEvent) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (!TwitchIntegrationManager.IsCheerEventEnabled) { return; } if (cheerEvent == null) { Logger.LogError("TwitchEventHandler: Failed to handle cheer. TwitchCheerEvent is null."); return; } if (!TwitchEventHandler.CanHandleEvents()) { TwitchEventHandler.ShowUnableToHandleEventsMessage(); return; } if (!TwitchIntegrationManager.CanPlayEvents()) { TwitchEventQueue.Enqueue(cheerEvent); return; } ViewerData viewerData = new ViewerData(((TwitchEvent)cheerEvent).User); int cheerAmount = cheerEvent.CheerAmount; if (!IsEnemySpawnEnabled && !IsEventSpawnEnabled) { MessageManager.Instance?.ShowMessage("Enemy and event spawns are disabled. " + GetAddingAccumulatedBitsMessage(viewerData, cheerAmount)); TwitchIntegrationManager.AddAccumulatedBits(viewerData, cheerAmount); return; } if (TryGetRandomProductForPrice(cheerAmount, out var product)) { switch (product.Type) { case ProductType.Enemy: HandleEnemySpawn(cheerEvent, viewerData, product.ToEnemyConfigEntry()); return; case ProductType.Event: HandleEventSpawn(cheerEvent, viewerData, product.ToMEvent()); return; case ProductType.RandomEnemy: HandleRandomEnemySpawn(cheerEvent, viewerData); return; case ProductType.RandomEvent: HandleRandomEventSpawn(cheerEvent, viewerData); return; } } if (!IsEnemySpawnEnabled) { MessageManager.Instance?.ShowMessage("Enemy spawns are disabled. " + GetAddingAccumulatedBitsMessage(viewerData, cheerAmount)); TwitchIntegrationManager.AddAccumulatedBits(viewerData, cheerAmount); return; } if (!ConfigManager.TwitchCheerEvent_EnableBitsForRandomEnemy.Value) { MessageManager.Instance?.ShowMessage("Random enemy spawns are disabled. " + GetAddingAccumulatedBitsMessage(viewerData, cheerAmount)); TwitchIntegrationManager.AddAccumulatedBits(viewerData, cheerAmount); return; } int accumulatedBits = TwitchIntegrationManager.GetAccumulatedBits(viewerData); int num = accumulatedBits + cheerAmount; int value = ConfigManager.TwitchCheerEvent_BitsForRandomEnemy.Value; if (num < value) { MessageManager.Instance?.ShowMessage(viewerData.GetDisplayNameWithColor() + " didn't cheer enough to spawn anything. " + GetAddingAccumulatedBitsMessage(viewerData, cheerAmount)); TwitchIntegrationManager.AddAccumulatedBits(viewerData, cheerAmount); return; } int spawnCount = Mathf.FloorToInt((float)(num / value)); int num2 = num % value; int accumulatedBitsUsedAmount = Mathf.Max(accumulatedBits - num2, 0); TwitchIntegrationManager.SetAccumulatedBits(viewerData, num2); HandleRandomEnemySpawn(cheerEvent, viewerData, spawnCount, accumulatedBitsUsedAmount); } private static string GetAddingAccumulatedBitsMessage(ViewerData viewer, int addedAmount) { int accumulatedBits = TwitchIntegrationManager.GetAccumulatedBits(viewer); int value = ConfigManager.TwitchCheerEvent_BitsForRandomEnemy.Value; return $"Adding {addedAmount} accumulated bits to {viewer.GetDisplayNameWithColor()} ({accumulatedBits + addedAmount}/{value})"; } private static void HandleEnemySpawn(TwitchCheerEvent cheerEvent, ViewerData viewer, EnemyConfigEntry enemyConfigEntry) { string spawnReason = $"by cheering {cheerEvent.CheerAmount} bits"; ViewerSpawnData viewerSpawnData = new ViewerSpawnData(viewer, 1, spawnReason, enemyConfigEntry.EnemyName); EnemyManager.SpawnEnemy(viewerSpawnData); } private static void HandleRandomEnemySpawn(TwitchCheerEvent cheerEvent, ViewerData viewer, int spawnCount = 1, int accumulatedBitsUsedAmount = 0) { string spawnReason; if (accumulatedBitsUsedAmount > 0) { int accumulatedBits = TwitchIntegrationManager.GetAccumulatedBits(viewer); spawnReason = $"by cheering {cheerEvent.CheerAmount} bits + {accumulatedBitsUsedAmount} accumulated bits. {accumulatedBits} accumulated bits remaining"; } else { spawnReason = $"by cheering {cheerEvent.CheerAmount} bits"; } ViewerSpawnData viewerSpawnData = new ViewerSpawnData(viewer, spawnCount, spawnReason); EnemyManager.SpawnEnemy(viewerSpawnData); } private static void HandleEventSpawn(TwitchCheerEvent cheerEvent, ViewerData viewer, MEvent mEvent) { mEvent.ExecuteEvent(viewer, PlayerAvatar.instance, cheerEvent.CheerAmount); } private static void HandleRandomEventSpawn(TwitchCheerEvent cheerEvent, ViewerData viewer) { if (!MEventManager.TryGetRandomEvent(out var mEvent)) { MessageManager.Instance?.ShowMessage("Failed to find random event. " + GetAddingAccumulatedBitsMessage(viewer, cheerEvent.CheerAmount)); } else { mEvent.ExecuteEvent(viewer, PlayerAvatar.instance, cheerEvent.CheerAmount); } } private static bool TryGetRandomProductForPrice(int value, out Product product) { List productsForPrice = GetProductsForPrice(value); if (productsForPrice == null || productsForPrice.Count == 0) { product = default(Product); return false; } product = productsForPrice[Random.Range(0, productsForPrice.Count)]; return true; } private static List GetProductsForPrice(int value) { List list = new List(); bool value2 = ConfigManager.TwitchCheerEvent_EnableBitsForRandomEnemy.Value; int value3 = ConfigManager.TwitchCheerEvent_BitsForRandomEnemy.Value; if (value2 && value3 == value) { list.Add(new Product(ProductType.RandomEnemy)); } foreach (EnemyConfigEntry enabledConfigEntry in EnemyConfigManager.EnabledConfigEntries) { if (enabledConfigEntry.BitsToSpawn.Value == value) { list.Add(new Product(enabledConfigEntry)); } } bool value4 = ConfigManager.Event_EnableBitsForRandomEvent.Value; int value5 = ConfigManager.Event_BitsForRandomEvent.Value; if (value4 && value5 == value) { list.Add(new Product(ProductType.RandomEvent)); } foreach (MEvent enabledEvent in MEventManager.EnabledEvents) { if (enabledEvent.BitsPrice.Value == value) { list.Add(new Product(enabledEvent)); } } return list; } } internal enum ProductType { Enemy, Event, RandomEnemy, RandomEvent } internal struct Product { public ProductType Type { get; set; } public object Data { get; set; } public Product(EnemyConfigEntry enemyConfigEntry) { this = default(Product); Type = ProductType.Enemy; Data = enemyConfigEntry; } public Product(MEvent mEvent) { this = default(Product); Type = ProductType.Event; Data = mEvent; } public Product(ProductType type) { this = default(Product); Type = type; } public EnemyConfigEntry ToEnemyConfigEntry() { return Data as EnemyConfigEntry; } public MEvent ToMEvent() { return Data as MEvent; } } internal static class TwitchEventHandler { public static void Initialize() { try { API.OnMessage += HandleMessage; API.OnCheer += HandleCheer; API.OnSub += HandleSub; API.OnRaid += HandleRaid; Application.quitting += delegate { API.OnMessage -= HandleMessage; API.OnCheer -= HandleCheer; API.OnSub -= HandleSub; API.OnRaid -= HandleRaid; }; } catch { Logger.LogFatal("TwitchEventHandler: Failed to initialize."); throw; } } public static void HandleMessage(TwitchMessage twitchMessage) { } public static void HandleCheer(TwitchCheerEvent cheerEvent) { TwitchCheerHandler.HandleCheer(cheerEvent); } public static void HandleSub(TwitchSubEvent subEvent) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Invalid comparison between Unknown and I4 //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Invalid comparison between Unknown and I4 //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if (!TwitchIntegrationManager.IsSubEventEnabled || !ConfigManager.Enemy_Enabled.Value) { return; } if (subEvent == null) { Logger.LogError("Failed to handle sub. TwitchSubEvent is null."); return; } if (!CanHandleEvents()) { ShowUnableToHandleEventsMessage(); return; } if (!TwitchIntegrationManager.CanPlayEvents()) { TwitchEventQueue.Enqueue(subEvent); return; } int num = 1; if ((int)subEvent.Type == 3) { num = subEvent.GiftCount; } string targetEnemyName = string.Empty; int num2 = 1; if (EnemyConfigManager.TryGetConfigEntriesThatMatchSubsAmount(num, out var list)) { if (list.TryGetRandom(out var enemyConfigEntry)) { targetEnemyName = enemyConfigEntry.EnemyName; } } else { num2 = num; } if ((int)subEvent.Tier < 2) { num2 *= ConfigManager.TwitchSubEvent_Tier1EnemySpawnCountMultiplier.Value; } else if ((int)subEvent.Tier == 2) { num2 *= ConfigManager.TwitchSubEvent_Tier2EnemySpawnCountMultiplier.Value; } else if ((int)subEvent.Tier == 3) { num2 *= ConfigManager.TwitchSubEvent_Tier3EnemySpawnCountMultiplier.Value; } ViewerSpawnData viewerSpawnData = new ViewerSpawnData(((TwitchEvent)subEvent).User, num2, GetSpawnReason(subEvent), targetEnemyName); Logger.LogInfo("HandleSub:\n" + JsonConvert.SerializeObject((object)viewerSpawnData, (Formatting)1), extended: true); EnemyManager.SpawnEnemy(viewerSpawnData); } public static void HandleRaid(TwitchRaidEvent raidEvent) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (TwitchIntegrationManager.IsRaidEventEnabled && ConfigManager.Enemy_Enabled.Value) { if (raidEvent == null) { Logger.LogError("TwitchEventHandler: Failed to handle raid. TwitchRaidEvent is null."); return; } if (!CanHandleEvents()) { ShowUnableToHandleEventsMessage(); return; } if (!TwitchIntegrationManager.CanPlayEvents()) { TwitchEventQueue.Enqueue(raidEvent); return; } int value = ConfigManager.TwitchRaidEvent_ViewersPerRandomEnemy.Value; int value2 = ConfigManager.TwitchRaidEvent_MaxEnemySpawnCount.Value; int spawnCount = Mathf.Clamp(raidEvent.ViewerCount / value, 1, value2); string spawnReason = $"by raiding with {raidEvent.ViewerCount} viewers"; ViewerSpawnData viewerSpawnData = new ViewerSpawnData(((TwitchEvent)raidEvent).User, spawnCount, spawnReason); Logger.LogInfo("HandleRaid:\n" + JsonConvert.SerializeObject((object)viewerSpawnData, (Formatting)1), extended: true); EnemyManager.SpawnEnemy(viewerSpawnData); } } private static string GetSpawnReason(TwitchSubEvent subEvent) { //IL_0010: 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_004c: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected I4, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Invalid comparison between Unknown and I4 //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected I4, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected I4, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected I4, but got Unknown if (subEvent == null) { return string.Empty; } string result = string.Empty; if ((int)subEvent.Type == 0) { result = (((int)subEvent.Tier != 0) ? $"by subbing at tier {(int)subEvent.Tier}" : "by subbing with prime"); } else if ((int)subEvent.Type == 1) { result = (((int)subEvent.Tier != 0) ? $"by resubbing at tier {(int)subEvent.Tier} for {subEvent.CumulativeMonths} months" : $"by resubbing with prime for {subEvent.CumulativeMonths} months"); } else if ((int)subEvent.Type == 2) { result = $"by gifting a tier {(int)subEvent.Tier} sub to {subEvent.RecipientUser}"; } else if ((int)subEvent.Type == 3) { result = $"by gifting {subEvent.GiftCount} tier {(int)subEvent.Tier} subs"; } return result; } public static void ShowUnableToHandleEventsMessage() { MessageManager.Instance?.ShowMessage("Warning! Triggering Twitch events is not currently supported on non-host clients\nDisable Twitch Chat API to hide these warnings"); } public static bool CanHandleEvents() { if (!PhotonNetwork.InRoom) { return true; } return SemiFunc.IsMasterClientOrSingleplayer(); } } internal static class TwitchEventQueue { [CompilerGenerated] private sealed class d__17 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public TimeSpan initialDelay; private TimeSpan 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__17(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown TwitchCheerEvent result; TwitchSubEvent result2; switch (<>1__state) { default: return false; case 0: <>1__state = -1; Logger.LogInfo("TwitchEventQueue: Started playing queued events.", extended: true); Logger.LogInfo($"TwitchEventQueue: Playing queued events after {(float)initialDelay.TotalSeconds} seconds.", extended: true); <>2__current = (object)new WaitForSeconds((float)initialDelay.TotalSeconds); <>1__state = 1; return true; case 1: <>1__state = -1; if (!TwitchEventHandler.CanHandleEvents()) { return false; } if (!TwitchIntegrationManager.CanPlayEvents()) { Logger.LogWarning("TwitchEventQueue: Failed to play queued events. You are not allowed to play events at this time."); return false; } if (!HasQueuedEvents()) { Logger.LogInfo("TwitchEventQueue: No events in the queue to play.", extended: true); return false; } MessageManager.Instance?.ShowMessage("Playing Twitch events from the queue"); 5__2 = TimeSpan.FromSeconds(0.5); goto IL_00d7; case 2: <>1__state = -1; goto IL_00d7; case 3: <>1__state = -1; goto IL_011b; case 4: { <>1__state = -1; break; } IL_00d7: if (TwitchIntegrationManager.IsCheerEventEnabled && CheerQueue.TryDequeue(out result)) { TwitchEventHandler.HandleCheer(result); <>2__current = (object)new WaitForSeconds((float)5__2.TotalSeconds); <>1__state = 2; return true; } goto IL_011b; IL_011b: if (TwitchIntegrationManager.IsSubEventEnabled && SubQueue.TryDequeue(out result2)) { TwitchEventHandler.HandleSub(result2); <>2__current = (object)new WaitForSeconds((float)5__2.TotalSeconds); <>1__state = 3; return true; } break; } if (TwitchIntegrationManager.IsRaidEventEnabled && RaidQueue.TryDequeue(out var result3)) { TwitchEventHandler.HandleRaid(result3); <>2__current = (object)new WaitForSeconds((float)5__2.TotalSeconds); <>1__state = 4; return true; } Logger.LogInfo("TwitchEventQueue: Finished plyaing queued events.", extended: true); SaveData(); _playQueuedEventsCoroutine = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static Coroutine _playQueuedEventsCoroutine; public static Queue CheerQueue { get; private set; } = new Queue(); public static Queue SubQueue { get; private set; } = new Queue(); public static Queue RaidQueue { get; private set; } = new Queue(); public static void LoadData() { Logger.LogInfo("TwitchEventQueue: Loading saved data..."); try { if (Plugin.GlobalSave.TryLoad("CheerQueue", out var value)) { CheerQueue = JsonConvertHelper.DeserializeQueue(value); Logger.LogInfo("TwitchEventQueue: Loaded CheerQueue JSON data:\n\n" + value, extended: true); } if (Plugin.GlobalSave.TryLoad("SubQueue", out value)) { SubQueue = JsonConvertHelper.DeserializeQueue(value); Logger.LogInfo("TwitchEventQueue: Loaded SubQueue JSON data:\n\n" + value, extended: true); } if (Plugin.GlobalSave.TryLoad("RaidQueue", out value)) { RaidQueue = JsonConvertHelper.DeserializeQueue(value); Logger.LogInfo("TwitchEventQueue: Loaded RaidQueue JSON data:\n\n" + value, extended: true); } Logger.LogInfo("TwitchEventQueue: Finished loading saved data."); } catch (Exception arg) { Logger.LogError($"TwitchEventQueue: Failed to load saved data. {arg}"); } } public static void SaveData() { Logger.LogInfo("TwitchEventQueue: Saving data...", extended: true); try { Plugin.GlobalSave.Save("CheerQueue", JsonConvertHelper.SerializeQueue(CheerQueue)); Plugin.GlobalSave.Save("SubQueue", JsonConvertHelper.SerializeQueue(SubQueue)); Plugin.GlobalSave.Save("RaidQueue", JsonConvertHelper.SerializeQueue(RaidQueue)); Logger.LogInfo("TwitchEventQueue: Saved data.", extended: true); } catch (Exception arg) { Logger.LogError($"TwitchEventQueue: Failed to save data. {arg}"); } } public static void PlayQueuedEvents() { PlayQueuedEvents(TimeSpan.Zero); } public static void PlayQueuedEvents(TimeSpan initialDelay) { if (!TwitchIntegrationManager.IsEnabled) { Logger.LogWarning("TwitchEventQueue: Failed to play queued events. Twitch integration is not enabled."); return; } if ((Object)(object)PluginManager.Instance == (Object)null) { Logger.LogError("TwitchEventQueue: Failed to play queued events. PluginManager instance is null."); return; } if (!TwitchIntegrationManager.CanPlayEvents()) { Logger.LogWarning("TwitchEventQueue: Failed to play queued events. You are not allowed to play events at this time."); return; } if (_playQueuedEventsCoroutine != null) { ((MonoBehaviour)PluginManager.Instance).StopCoroutine(_playQueuedEventsCoroutine); } _playQueuedEventsCoroutine = ((MonoBehaviour)PluginManager.Instance).StartCoroutine(PlayQueuedEventsCoroutine(initialDelay)); } [IteratorStateMachine(typeof(d__17))] private static IEnumerator PlayQueuedEventsCoroutine(TimeSpan initialDelay) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__17(0) { initialDelay = initialDelay }; } public static bool HasQueuedEvents() { if (CheerQueue.Count <= 0 && SubQueue.Count <= 0) { return RaidQueue.Count > 0; } return true; } public static void Enqueue(TwitchCheerEvent cheerEvent) { if (!CheerQueue.Contains(cheerEvent)) { CheerQueue.Enqueue(cheerEvent); SaveData(); ShowEnqueueMessage((TwitchEvent)(object)cheerEvent, "cheer"); } } public static void Enqueue(TwitchSubEvent subEvent) { if (!SubQueue.Contains(subEvent)) { SubQueue.Enqueue(subEvent); SaveData(); ShowEnqueueMessage((TwitchEvent)(object)subEvent, "sub"); } } public static void Enqueue(TwitchRaidEvent raidEvent) { if (!RaidQueue.Contains(raidEvent)) { RaidQueue.Enqueue(raidEvent); SaveData(); ShowEnqueueMessage((TwitchEvent)(object)raidEvent, "raid"); } } private static void ShowEnqueueMessage(TwitchEvent twitchEvent, string eventName) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) string displayNameWithColor = twitchEvent.User.GetDisplayNameWithColor(); string message = "Added Twitch " + eventName + " event from " + displayNameWithColor + " to queue"; MessageManager.Instance?.ShowMessage(message); } } internal static class TwitchIntegrationManager { public static Dictionary AccumulatedBits { get; private set; } = new Dictionary(); public static bool IsEnabled => ConfigManager.TwitchIntegration_Enabled.Value; public static bool IsCheerEventEnabled { get { if (IsEnabled) { return ConfigManager.TwitchCheerEvent_Enabled.Value; } return false; } } public static bool IsSubEventEnabled { get { if (IsEnabled) { return ConfigManager.TwitchSubEvent_Enabled.Value; } return false; } } public static bool IsRaidEventEnabled { get { if (IsEnabled) { return ConfigManager.TwitchRaidEvent_Enabled.Value; } return false; } } public static void Initialize() { LoadData(); Application.quitting += SaveData; TwitchEventHandler.Initialize(); } private static void LoadData() { Logger.LogInfo("TwitchIntegrationManager: Loading saved data..."); try { TwitchEventQueue.LoadData(); LoadAccumulatedBits(); Logger.LogInfo("TwitchIntegrationManager: Finished loading saved data."); } catch (Exception arg) { Logger.LogError($"TwitchIntegrationManager: Failed to load saved data. {arg}"); } } public static void SaveData() { Logger.LogInfo("TwitchIntegrationManager: Saving data..."); try { TwitchEventQueue.SaveData(); SaveAccumulatedBits(); Logger.LogInfo("TwitchIntegrationManager: Saved data."); } catch (Exception arg) { Logger.LogError($"TwitchIntegrationManager: Failed to save data. {arg}"); } } private static void LoadAccumulatedBits() { try { if (Plugin.GlobalSave.TryLoad("AccumulatedBits", out var value)) { AccumulatedBits = JsonConvert.DeserializeObject>(value); Logger.LogInfo("TwitchIntegrationManager: Loaded AccumulatedBits JSON data:\n\n" + value, extended: true); } } catch (Exception arg) { Logger.LogError($"TwitchIntegrationManager: Failed to load AccumulatedBits from saved data. {arg}"); } } public static void SaveAccumulatedBits() { Plugin.GlobalSave.Save("AccumulatedBits", JsonConvert.SerializeObject((object)AccumulatedBits)); } public static int GetAccumulatedBits(ViewerData viewer) { if (viewer == null) { return 0; } return GetAccumulatedBits(viewer.Username); } public static int GetAccumulatedBits(string username) { return AccumulatedBits.GetValueOrDefault(username.ToLower(), 0); } public static void SetAccumulatedBits(ViewerData viewer, int value) { if (viewer != null) { if (value <= 0) { AccumulatedBits.Remove(viewer.Username); } else { AccumulatedBits[viewer.Username] = value; } SaveAccumulatedBits(); } } public static void AddAccumulatedBits(ViewerData viewer, int value) { int accumulatedBits = GetAccumulatedBits(viewer); SetAccumulatedBits(viewer, accumulatedBits + value); } public static bool CanPlayEvents() { if (!IsEnabled) { return false; } return EnemyManager.CanSpawnEnemies(); } } } namespace com.github.zehsteam.TwitchTrolling.Twitch.Objects { [Serializable] public class ViewerData { public string UserId { get; } public string Username => DisplayName.ToLower(); public string DisplayName { get; } public string Color { get; } public ViewerData(string userId, string displayName, string color) { UserId = userId; DisplayName = displayName; Color = color; } public ViewerData(TwitchUser twitchUser) { UserId = ((TwitchUser)(ref twitchUser)).UserId; DisplayName = ((TwitchUser)(ref twitchUser)).DisplayName; Color = ((TwitchUser)(ref twitchUser)).Color; } public string GetDisplayNameWithColor() { return Utils.GetTextWithReadableColor(DisplayName, Color); } } [Serializable] public class ViewerSpawnData { public ViewerData Viewer { get; private set; } public int SpawnCount { get; private set; } public string SpawnReason { get; private set; } public string TargetEnemyName { get; private set; } public int TotalSpawnCount { get; private set; } public ViewerSpawnData(ViewerData viewer, int spawnCount, string spawnReason, string targetEnemyName = "") { Viewer = viewer; SpawnCount = spawnCount; SpawnReason = spawnReason; TargetEnemyName = targetEnemyName; } public ViewerSpawnData(TwitchUser twitchUser, int spawnCount, string spawnReason, string targetEnemyName = "") { //IL_0007: Unknown result type (might be due to invalid IL or missing references) Viewer = new ViewerData(twitchUser); SpawnCount = spawnCount; SpawnReason = spawnReason; TargetEnemyName = targetEnemyName; } public void SetTargetEnemyName(string value) { TargetEnemyName = value; } public void SetTotalSpawnCount(int value) { TotalSpawnCount = value; } } } namespace com.github.zehsteam.TwitchTrolling.Twitch.Helpers { internal static class TwitchHelper { public static TwitchUser CreateTwitchUser(bool isVIP = false, bool isSubscriber = false, bool isModerator = false, bool isBroadcaster = false) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (PlayerHelper.TryGetLocalPlayer(out var playerAvatar)) { string steamID = playerAvatar.steamID; string displayName = SemiFunc.PlayerGetName(playerAvatar); string color = "#FFFFFF"; return CreateTwitchUser(steamID, displayName, color, isVIP, isSubscriber, isModerator, isBroadcaster); } return CreateTwitchUser("0", "Unknown", "#FFFFFF", isVIP, isSubscriber, isModerator, isBroadcaster); } public static TwitchUser CreateTwitchUser(string userId, string displayName, string color = "#FFFFFF", bool isVIP = false, bool isSubscriber = false, bool isModerator = false, bool isBroadcaster = false) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) TwitchUser result = default(TwitchUser); ((TwitchUser)(ref result)).UserId = userId; ((TwitchUser)(ref result)).Username = displayName.ToLower(); ((TwitchUser)(ref result)).DisplayName = displayName; ((TwitchUser)(ref result)).Color = color; ((TwitchUser)(ref result)).IsVIP = isVIP; ((TwitchUser)(ref result)).IsSubscriber = isSubscriber; ((TwitchUser)(ref result)).IsModerator = isModerator; ((TwitchUser)(ref result)).IsBroadcaster = isBroadcaster; return result; } } } namespace com.github.zehsteam.TwitchTrolling.Twitch.Commands { internal static class TwitchSimulateCheerCommand { public static void Register() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown ChatCommand val = new ChatCommand("cheer", "Simulate a Twitch cheer for TwitchTrolling", (Action)Execute, (Func>)Suggest, (Func)IsEnabled, false); Commands.RegisterCommand(val); } private static void Execute(bool isDebugConsole, string[] args) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_003b: Expected O, but got Unknown int cheerAmount = ConfigManager.TwitchCheerEvent_BitsForRandomEnemy.Value; if (args.Length >= 1 && int.TryParse(args[0], out var result)) { cheerAmount = result; } TwitchCheerEvent cheerEvent = new TwitchCheerEvent { User = TwitchHelper.CreateTwitchUser(), CheerAmount = cheerAmount }; TwitchEventHandler.HandleCheer(cheerEvent); DebugCommandHandler instance = DebugCommandHandler.instance; if (instance != null) { instance.CommandSuccessEffect(); } } private static List Suggest(bool isDebugConsole, string partial, string[] args) { List list = new List(); List list2 = new List(); foreach (EnemyConfigEntry enabledConfigEntry in EnemyConfigManager.EnabledConfigEntries) { list.Add(new SuggestEntry(enabledConfigEntry.EnemyName, enabledConfigEntry.BitsToSpawn.Value)); } foreach (MEvent enabledEvent in MEventManager.EnabledEvents) { list.Add(new SuggestEntry(enabledEvent.Name, enabledEvent.BitsPrice.Value)); } foreach (SuggestEntry item in list) { int price = item.Price; string name = item.Name; bool flag = true; foreach (CombinedSuggestEntry item2 in list2) { if (item2.Price == price) { item2.Names.Add(name); flag = false; break; } } if (flag) { list2.Add(new CombinedSuggestEntry(name, price)); } } List list3 = (from x in list2 where x.Matches(args) orderby x.Price select x.GetText()).ToList(); if (ConfigManager.Event_EnableBitsForRandomEvent.Value) { CombinedSuggestEntry combinedSuggestEntry = new CombinedSuggestEntry("RANDOM EVENT", ConfigManager.Event_BitsForRandomEvent.Value); if (combinedSuggestEntry.Matches(args)) { list3.Insert(0, combinedSuggestEntry.GetText()); } } if (ConfigManager.TwitchCheerEvent_EnableBitsForRandomEnemy.Value) { CombinedSuggestEntry combinedSuggestEntry2 = new CombinedSuggestEntry("RANDOM ENEMY", ConfigManager.TwitchCheerEvent_BitsForRandomEnemy.Value); if (combinedSuggestEntry2.Matches(args)) { list3.Insert(0, combinedSuggestEntry2.GetText()); } } return list3; } private static bool IsEnabled() { if (SemiFunc.IsSplashScreen() || SemiFunc.IsMainMenu()) { return false; } if (SemiFunc.RunIsLobbyMenu()) { return false; } if (SemiFunc.RunIsTutorial()) { return false; } if (!SemiFunc.IsMasterClientOrSingleplayer()) { return false; } return true; } } internal static class TwitchSimulateSubCommand { public static void Register() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown ChatCommand val = new ChatCommand("sub", "Simulate a Twitch sub or gift subs for TwitchTrolling", (Action)Execute, (Func>)Suggest, (Func)IsEnabled, false); Commands.RegisterCommand(val); } private static void Execute(bool isDebugConsole, string[] args) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown int giftCount = 1; if (args.Length != 0 && int.TryParse(args[0], out var result)) { giftCount = result; } TwitchSubEvent subEvent = new TwitchSubEvent { User = TwitchHelper.CreateTwitchUser(), Type = (SubType)3, Tier = (SubTier)1, GiftCount = giftCount }; TwitchEventHandler.HandleSub(subEvent); DebugCommandHandler instance = DebugCommandHandler.instance; if (instance != null) { instance.CommandSuccessEffect(); } } private static List Suggest(bool isDebugConsole, string partial, string[] args) { List list = new List(); List list2 = new List(); foreach (EnemyConfigEntry enabledConfigEntry in EnemyConfigManager.EnabledConfigEntries) { list.Add(new SuggestEntry(enabledConfigEntry.EnemyName, enabledConfigEntry.SubsToSpawn.Value)); } foreach (SuggestEntry item in list) { int price = item.Price; string name = item.Name; bool flag = true; foreach (CombinedSuggestEntry item2 in list2) { if (item2.Price == price) { item2.Names.Add(name); flag = false; break; } } if (flag) { list2.Add(new CombinedSuggestEntry(name, price)); } } return (from x in list2 where x.Matches(args) orderby x.Price select x.GetText()).ToList(); } private static bool IsEnabled() { if (SemiFunc.IsSplashScreen() || SemiFunc.IsMainMenu()) { return false; } if (SemiFunc.RunIsLobbyMenu()) { return false; } if (SemiFunc.RunIsTutorial()) { return false; } if (!SemiFunc.IsMasterClientOrSingleplayer()) { return false; } return true; } } } namespace com.github.zehsteam.TwitchTrolling.Twitch.Commands.Objects { internal class CombinedSuggestEntry { public List Names = new List(); public int Price; public CombinedSuggestEntry(string name, int price) { Names = new List(1) { name }; Price = price; } public string GetText() { return $"{Price} - {GetNames()}"; } public string GetNames() { if (Names.Count == 1) { return Names[0]; } string text = string.Empty; int num = 60; int num2 = Names.Count; for (int i = 0; i < Names.Count; i++) { string text2 = string.Empty; if (i > 0) { text2 += ", "; } text2 += Names[i]; if ((text + text2).Length > num) { break; } text += text2; num2--; } if (num2 > 0) { text = text.Substring(0, Math.Min(text.Length, num)); text += $"... +{num2}"; } return text; } public bool Matches(string[] args) { string value = string.Join(" ", args); if (Price.ToString().StartsWith(value)) { return true; } if (Names.Any((string x) => x.Contains(value, StringComparison.OrdinalIgnoreCase))) { return true; } if (value.StartsWith(Price.ToString(), StringComparison.OrdinalIgnoreCase) && GetText().StartsWith(value, StringComparison.OrdinalIgnoreCase)) { return true; } return false; } } internal struct SuggestEntry { public string Name { get; set; } public int Price { get; set; } public SuggestEntry(string name, int price) { Name = name; Price = price; } } } namespace com.github.zehsteam.TwitchTrolling.Patches { [HarmonyPatch(typeof(EnemyDirector))] internal static class EnemyDirectorPatch { private static bool _patchedStart; [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch() { if (!_patchedStart) { _patchedStart = true; EnemyConfigManager.Initialize(); PageManager.UpdatePageFirstTime(); } } } [HarmonyPatch(typeof(EnemyDuck))] internal static class EnemyDuckPatch { public static List DucksToBypassStunAggroOnce = new List(); public static void Reset() { DucksToBypassStunAggroOnce = new List(); } [HarmonyPatch("StateStun")] [HarmonyTranspiler] private static IEnumerable StateStunTranspiler(IEnumerable instructions) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown string text = "EnemyDuckPatch: [StateStun Transpiler]"; MethodInfo methodInfo = AccessTools.Method(typeof(EnemyDuck), "UpdateState", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(EnemyDuckPatch), "StateStun_UpdateState", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { Logger.LogError(text + " Failed to create transpiler. Required methods not found."); return instructions; } List list = new List(); foreach (CodeInstruction instruction in instructions) { if (CodeInstructionExtensions.Calls(instruction, methodInfo)) { list.Add(new CodeInstruction(OpCodes.Call, (object)methodInfo2)); Logger.LogInfo(text + " Replaced " + methodInfo.Name + " call with " + methodInfo2.Name + ".", extended: true); } else { list.Add(instruction); } } return list.AsEnumerable(); } private static void StateStun_UpdateState(EnemyDuck enemyDuck, State state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) if ((int)state == 11 && DucksToBypassStunAggroOnce.Contains(enemyDuck)) { DucksToBypassStunAggroOnce.Remove(enemyDuck); enemyDuck.UpdateState((State)1); } else { enemyDuck.UpdateState(state); } } } [HarmonyPatch(typeof(FanTrap))] internal static class FanTrapPatch { public static List FansToBypassIdle = new List(); [HarmonyPatch("SetState")] [HarmonyPrefix] private static bool SetStatePatch(FanTrap __instance, States state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if ((int)state != 0) { return true; } if (FansToBypassIdle.Contains(__instance)) { return false; } return true; } } [HarmonyPatch(typeof(HUDCanvas))] internal static class HUDCanvasPatch { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AwakePatch(HUDCanvas __instance) { Transform parent = ((Component)__instance).transform.Find("HUD"); PluginHUD.Spawn(parent); } } [HarmonyPatch(typeof(ItemDrone))] internal static class ItemDronePatch { public static List IgnorePhysGrabObjects = new List(); [HarmonyPatch("NewRayHitPointLogic")] [HarmonyPrefix] private static bool NewRayHitPointLogicPatch(ItemDrone __instance, int photonViewId, Transform newMagnetTarget) { PhysGrabObject physGrabObject = ((!((Object)(object)newMagnetTarget != (Object)null)) ? ((Component)PhotonView.Find(photonViewId)).gameObject.GetComponent() : ((Component)newMagnetTarget).GetComponent()); return CanAttachToPhysGrabObject(__instance, physGrabObject); } [HarmonyPatch("GetHighestParentWithRigidbody")] [HarmonyPostfix] private static void GetHighestParentWithRigidbodyPatch(ItemDrone __instance, ref Transform __result) { PhysGrabObject physGrabObject = default(PhysGrabObject); if (!((Object)(object)__result == (Object)null) && ((Component)__result).TryGetComponent(ref physGrabObject) && !CanAttachToPhysGrabObject(__instance, physGrabObject)) { __result = null; } } private static bool CanAttachToPhysGrabObject(ItemDrone itemDrone, PhysGrabObject physGrabObject) { if ((Object)(object)itemDrone == (Object)null || (Object)(object)physGrabObject == (Object)null) { return true; } if (IsSameDroneType(itemDrone, physGrabObject)) { return false; } if (IgnorePhysGrabObjects.Contains(physGrabObject)) { return false; } return true; } private static bool IsSameDroneType(ItemDrone itemDrone, PhysGrabObject physGrabObject) { if ((Object)(object)itemDrone == (Object)null || (Object)(object)physGrabObject == (Object)null) { return false; } ItemAttributes val = default(ItemAttributes); if (!((Component)physGrabObject).TryGetComponent(ref val)) { return false; } return itemDrone.itemAttributes.itemName == val.itemName; } } [HarmonyPatch(typeof(ItemRubberDuck))] internal static class ItemRubberDuckPatch { public static List SpecialRubberDucks = new List(); [HarmonyPatch("Quack")] [HarmonyPostfix] private static void QuackPatch(ItemRubberDuck __instance) { //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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (SpecialRubberDucks.Contains(__instance) && SemiFunc.IsMasterClientOrSingleplayer() && !(__instance.itemBattery.batteryLife <= 0f) && !__instance.physGrabObject.grabbed) { Vector3 velocity = __instance.rb.velocity; if (((Vector3)(ref velocity)).magnitude >= 20f) { Rigidbody rb = __instance.rb; rb.velocity *= 5f; __instance.rb.AddTorque(Random.insideUnitSphere * 40f); } } } } [HarmonyPatch(typeof(LevelGenerator))] internal static class LevelGeneratorPatch { [HarmonyPatch("EnemySetup")] [HarmonyPostfix] private static void EnemySetupPatch() { EnemyManager.ResetViewerEnemies(); EnemyDuckPatch.Reset(); if (TwitchIntegrationManager.CanPlayEvents()) { TwitchEventQueue.PlayQueuedEvents(TimeSpan.FromSeconds(10.0)); } } } [HarmonyPatch(typeof(PlayerController))] internal static class PlayerControllerPatch { private static bool _usingCustomSpeed; private static float _timeCustomSpeedEnd = float.NegativeInfinity; private static bool _usingCustomGravity; private static float _timeCustomGravityEnd = float.NegativeInfinity; [HarmonyPatch("Update")] [HarmonyPostfix] private static void UpdatePatch() { if (_usingCustomSpeed && !IsSpeedOverwritten()) { _usingCustomSpeed = false; ResetSpeed(); } if (_usingCustomGravity && !IsGravityOverwritten()) { _usingCustomGravity = false; ResetGravity(); } } public static void OverrideSpeed(float value, TimeSpan duration) { if (!((Object)(object)PlayerController.instance == (Object)null)) { _usingCustomSpeed = true; SetSpeed(value); _timeCustomSpeedEnd = Time.realtimeSinceStartup + (float)duration.TotalSeconds; } } private static bool IsSpeedOverwritten() { return Time.realtimeSinceStartup < _timeCustomSpeedEnd; } private static void SetSpeed(float value) { if (!((Object)(object)PlayerController.instance == (Object)null)) { value += 5f; PlayerController.instance.CrouchSpeed = value; PlayerController.instance.MoveSpeed = value; PlayerController.instance.SprintSpeed = value; } } private static void ResetSpeed() { if (!((Object)(object)PlayerAvatar.instance == (Object)null) && !((Object)(object)StatsManager.instance == (Object)null)) { PlayerController.instance.OverrideSpeed(1f, 0.1f); MessageManager.Instance?.ShowMessage("Your speed has been reset"); } } public static void OverrideGravity(float value, TimeSpan duration) { if (!((Object)(object)PlayerController.instance == (Object)null)) { _usingCustomGravity = true; SetGravity(value); _timeCustomGravityEnd = Time.realtimeSinceStartup + (float)duration.TotalSeconds; } } private static bool IsGravityOverwritten() { return Time.realtimeSinceStartup < _timeCustomGravityEnd; } private static void SetGravity(float value) { if (!((Object)(object)PlayerController.instance == (Object)null)) { PlayerController.instance.CustomGravity = value; } } private static void ResetGravity() { if (!((Object)(object)PlayerAvatar.instance == (Object)null) && !((Object)(object)StatsManager.instance == (Object)null)) { PlayerController.instance.CustomGravity = PlayerController.instance.playerOriginalCustomGravity; } } } [HarmonyPatch(typeof(RunManager))] internal static class RunManagerPatch { private static bool _patchedAwake; [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AwakePatch(RunManager __instance) { if (!_patchedAwake) { _patchedAwake = true; MEventManager.Initialize(); } } } [HarmonyPatch(typeof(TruckScreenText))] internal static class TruckScreenTextPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch() { SpawnTruckProps(); } private static void SpawnTruckProps() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (TryGetTruckMeshTransform(out var transform)) { GameObject val = Object.Instantiate(Assets.TruckPropsPrefab); val.transform.SetParent(transform); val.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); Logger.LogInfo("TruckScreenTextPatch: Spawned truck props.", extended: true); } } private static bool TryGetTruckMeshTransform(out Transform transform) { transform = null; if ((Object)(object)TruckScreenText.instance == (Object)null) { Logger.LogInfo("TruckScreenTextPatch: Failed to get truck mesh transform. TruckScreenText instance is null."); return false; } try { transform = ((Component)TruckScreenText.instance).transform.parent.Find("Mesh"); return true; } catch (Exception arg) { Logger.LogInfo($"TruckScreenTextPatch: Failed to get truck mesh transform. {arg}"); return false; } } } } namespace com.github.zehsteam.TwitchTrolling.Objects { [Serializable] public class AudioPlayerFactory { public enum AudioUseMode { Single, Reuse } private static Dictionary> _audioPlayerPool = new Dictionary>(); public AudioPlayer AudioPlayer; public AudioPlayerType Type; public AudioUseMode UseMode; public float Volume = 1f; public float MaxDistance = 15f; public bool IsPlaying => AudioPlayer?.IsPlaying ?? false; public float Play(AudioClip audioClip, Vector3 position, bool loop = false) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) AssignAudioPlayer(); if (UseMode != AudioUseMode.Reuse) { loop = false; } return AudioPlayer?.Play(audioClip, position, Volume, MaxDistance, loop) ?? 0f; } public float Play(AudioClip audioClip, Transform transform, bool loop = false) { AssignAudioPlayer(); if (UseMode != AudioUseMode.Reuse) { loop = false; } return AudioPlayer?.Play(audioClip, transform, Volume, MaxDistance, loop) ?? 0f; } public void Stop() { AudioPlayer?.Stop(); } public void SetTargetTransform(Transform targetTransform) { AudioPlayer?.SetTargetTransform(targetTransform); } public void SetTargetPosition(Vector3 targetPosition) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) AudioPlayer?.SetTargetPosition(targetPosition); } private void AssignAudioPlayer() { if (UseMode == AudioUseMode.Single) { AudioPlayer = GetAudioPlayer(); } else if (UseMode == AudioUseMode.Reuse) { if ((Object)(object)AudioPlayer == (Object)null || (Object)(object)((Component)AudioPlayer).gameObject == (Object)null) { AudioPlayer = GetAudioPlayer(); } if (!((Object)(object)AudioPlayer == (Object)null) && !((Component)AudioPlayer).gameObject.activeSelf) { ((Component)AudioPlayer).gameObject.SetActive(true); } } } private GameObject GetAudioPrefab() { if ((Object)(object)AudioManager.instance == (Object)null) { return null; } return (GameObject)(Type switch { AudioPlayerType.Default => AudioManager.instance.AudioDefault, AudioPlayerType.EnemySpawn => Assets.AudioEnemySpawnPrefab, _ => null, }); } private AudioPlayer GetAudioPlayer() { if (!_audioPlayerPool.TryGetValue(Type, out var value) || value.Count == 0) { return CreateAudioPlayer(); } AudioPlayer audioPlayer = value.Dequeue(); if ((Object)(object)audioPlayer == (Object)null || (Object)(object)((Component)audioPlayer).gameObject == (Object)null) { return CreateAudioPlayer(); } ((Component)audioPlayer).gameObject.SetActive(false); ((Component)audioPlayer).gameObject.SetActive(true); return audioPlayer; } private AudioPlayer CreateAudioPlayer() { if ((Object)(object)AudioManager.instance == (Object)null) { return null; } GameObject audioPrefab = GetAudioPrefab(); if ((Object)(object)audioPrefab == (Object)null) { return null; } GameObject val = Object.Instantiate(audioPrefab); ((Object)val).name = $"AudioPlayer {Type}"; AudioPlayer audioPlayer = val.AddComponent(); audioPlayer.Type = Type; if ((Object)(object)PluginManager.Instance != (Object)null) { val.transform.SetParent(PluginManager.Instance.AudioPlayerContainerTransform); } return audioPlayer; } public static void AddToPool(AudioPlayer audioPlayer) { if (!((Object)(object)audioPlayer == (Object)null) && !((Object)(object)((Component)audioPlayer).gameObject == (Object)null)) { if (!_audioPlayerPool.TryGetValue(audioPlayer.Type, out var value)) { value = new Queue(); _audioPlayerPool.Add(audioPlayer.Type, value); } value.Enqueue(audioPlayer); ((Component)audioPlayer).gameObject.SetActive(false); } } } public class EnemyConfigEntry { private readonly EnemyConfigEntryDefaultValues _defaultValues; public string EnemyName { get; private set; } public ConfigEntry Enabled { get; private set; } public ConfigEntry SpawnCount { get; private set; } public ConfigEntry BitsToSpawn { get; private set; } public ConfigEntry SubsToSpawn { get; private set; } public EnemyConfigEntry(string enemyName) { _defaultValues = new EnemyConfigEntryDefaultValues(enemyName); Initialize(); } public EnemyConfigEntry(EnemyConfigEntryDefaultValues defaultValues) { _defaultValues = defaultValues; Initialize(); } private void Initialize() { if (_defaultValues != null) { EnemyName = _defaultValues.EnemyName; BindConfigs(); } } private void BindConfigs() { string text = "Enemy: " + EnemyName; Enabled = EnemyConfigManager.ConfigFile.Bind(text, "Enabled", _defaultValues.Enabled, "Enable the " + EnemyName + " to be able to spawn."); SpawnCount = EnemyConfigManager.ConfigFile.Bind(text, "SpawnCount", _defaultValues.SpawnCount, "The amount of " + EnemyName + " to spawn.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 20)); BitsToSpawn = EnemyConfigManager.ConfigFile.Bind(text, "BitsToSpawn", _defaultValues.BitsToSpawn, "The amount of bits to spawn " + EnemyName + ".", (AcceptableValueBase)(object)new AcceptableValueRange(1, 1000)); SubsToSpawn = EnemyConfigManager.ConfigFile.Bind(text, "SubsToSpawn", _defaultValues.SubsToSpawn, "The amount of subs to spawn " + EnemyName + ".", (AcceptableValueBase)(object)new AcceptableValueRange(1, 10)); Enabled.SettingChanged += delegate { PageManager.UpdatePage(); }; SpawnCount.SettingChanged += delegate { PageManager.UpdatePage(); }; BitsToSpawn.SettingChanged += delegate { PageManager.UpdatePage(); }; SubsToSpawn.SettingChanged += delegate { PageManager.UpdatePage(); }; } public bool EnemyNameEquals(string enemyName) { return EnemyName.Equals(enemyName, StringComparison.OrdinalIgnoreCase); } public JObject GetCardJSON() { //IL_0038: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown int num = 1; int value = SpawnCount.Value; if (EnemyName.Equals("Banger", StringComparison.OrdinalIgnoreCase)) { num = 3; } if (EnemyName.Equals("Gnome", StringComparison.OrdinalIgnoreCase)) { num = 4; } JObject val = new JObject { ["name"] = JToken.op_Implicit(EnemyName), ["price"] = JToken.op_Implicit(BitsToSpawn.Value), ["spawnCount"] = JToken.op_Implicit(num * value) }; if (ConfigManager.TwitchSubEvent_Enabled.Value) { val.Add("subPrice", JToken.op_Implicit(SubsToSpawn.Value)); } return val; } } [Serializable] public class EnemyConfigEntryDefaultValues { public string EnemyName; public bool Enabled = true; public int SpawnCount = 1; public int BitsToSpawn = 350; public int SubsToSpawn = 1; public EnemyConfigEntryDefaultValues(string enemyName) { EnemyName = enemyName; } public EnemyConfigEntryDefaultValues(string enemyName, bool enabled, int spawnCount, int bitsToSpawn, int subsToSpawn) : this(enemyName) { Enabled = enabled; SpawnCount = spawnCount; BitsToSpawn = bitsToSpawn; SubsToSpawn = subsToSpawn; } } [CreateAssetMenu(fileName = "EnemyConfigEntryDefaultValuesList", menuName = "TwitchTrolling/EnemyConfigEntryDefaultValuesList")] public class EnemyConfigEntryDefaultValuesList : ScriptableObject { public EnemyConfigEntryDefaultValues[] List = Array.Empty(); } [Serializable] public class EnemySpawnSFX { public string EnemyName; public AudioClip SpawnSFX; public EnemySpawnSFX(string enemyName, AudioClip spawnSFX) { EnemyName = enemyName; SpawnSFX = spawnSFX; } } [CreateAssetMenu(fileName = "EnemySpawnSFXList", menuName = "TwitchTrolling/EnemySpawnSFXList")] public class EnemySpawnSFXList : ScriptableObject { public AudioClip GenericSpawnSFX; public EnemySpawnSFX[] List = Array.Empty(); public AudioClip GetSpawnSFX(string enemyName) { EnemySpawnSFX[] list = List; foreach (EnemySpawnSFX enemySpawnSFX in list) { if (enemySpawnSFX.EnemyName.Equals(enemyName, StringComparison.OrdinalIgnoreCase)) { return enemySpawnSFX.SpawnSFX; } } return GenericSpawnSFX; } } internal class JsonSave { private JObject _data; public string DirectoryPath { get; private set; } public string FileName { get; private set; } public string FilePath => Path.Combine(DirectoryPath, FileName); public JsonSave(string directoryPath, string fileName) { DirectoryPath = directoryPath; FileName = fileName; _data = ReadFile(); } public bool KeyExists(string key) { if (_data == null) { Logger.LogError("KeyExists: Data is null. Ensure the save file is properly loaded."); return false; } return _data.ContainsKey(key); } public T Load(string key, T defaultValue = default(T), bool readFile = false) { if (TryLoad(key, out var value, readFile)) { return value; } return defaultValue; } public bool TryLoad(string key, out T value, bool readFile = false) { //IL_0058: Expected O, but got Unknown value = default(T); if (readFile) { _data = ReadFile(); } if (_data == null) { Logger.LogError("Load: Data is null. Returning default value for key: " + key + "."); return false; } JToken val = default(JToken); if (_data.TryGetValue(key, ref val)) { try { value = val.ToObject(); return true; } catch (JsonException val2) { JsonException val3 = val2; Logger.LogError("Load: JSON Conversion Error for key: " + key + ". " + ((Exception)(object)val3).Message); } catch (ArgumentNullException ex) { Logger.LogError("Load: Argument Null Error for key: " + key + ". " + ex.Message); } catch (Exception ex2) { Logger.LogError("Load: Unexpected Error for key: " + key + ". " + ex2.Message); } return false; } Logger.LogWarning("Load: Key '" + key + "' does not exist. Returning default value.", extended: true); return false; } public bool Save(string key, T value) { if (_data == null) { Logger.LogError("Save: Data is null. Cannot save key: " + key + "."); return false; } try { JToken val = JToken.FromObject((object)value); if (_data.ContainsKey(key)) { _data[key] = val; } else { _data.Add(key, val); } return WriteFile(_data); } catch (Exception ex) { Logger.LogError("Save: Error saving key: " + key + ". " + ex.Message); return false; } } private JObject ReadFile() { //IL_0070: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown try { if (!File.Exists(FilePath)) { Logger.LogWarning("ReadFile: Save file does not exist at \"" + FilePath + "\". Initializing with an empty file.", extended: true); return new JObject(); } using FileStream stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read); using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8); return JObject.Parse(streamReader.ReadToEnd()); } catch (JsonException val) { JsonException val2 = val; Logger.LogError("ReadFile: JSON Parsing Error for file: \"" + FilePath + "\". " + ((Exception)(object)val2).Message); } catch (Exception ex) { Logger.LogError("ReadFile: Unexpected Error for file: \"" + FilePath + "\". " + ex.Message); } return new JObject(); } private bool WriteFile(JObject data) { try { if (!Directory.Exists(DirectoryPath)) { Directory.CreateDirectory(DirectoryPath); } File.WriteAllText(FilePath, ((object)data).ToString(), Encoding.UTF8); return true; } catch (Exception ex) { Logger.LogError("WriteFile: Unexpected Error for file: \"" + FilePath + "\". " + ex.Message); } return false; } } internal class JsonSaveValue : ObservableValue { public JsonSave JsonSave { get; private set; } public string Key { get; private set; } public T DefaultValue { get; private set; } public bool ReadFile { get; private set; } public bool HasValue { get { T value; return TryLoad(out value); } } public JsonSaveValue(JsonSave jsonSave, string key, T defaultValue = default(T), bool readFile = false) : base(default(T)) { JsonSave = jsonSave; Key = key; DefaultValue = defaultValue; ReadFile = readFile; CustomValueGetter = Load; CustomValueSetter = Save; } private T Load() { return JsonSave.Load(Key, DefaultValue, ReadFile); } private bool TryLoad(out T value) { return JsonSave.TryLoad(Key, out value, ReadFile); } private void Save(T value) { if (!object.Equals(value, base.Value)) { JsonSave.Save(Key, value); } } } internal class ObservableValue { protected T _value; protected Func CustomValueGetter; protected Action CustomValueSetter; public T Value { get { return GetValue(); } set { SetValue(value); } } public event Action OnValueChanged; public ObservableValue(T initialValue = default(T)) { _value = initialValue; } private T GetValue() { if (CustomValueGetter != null) { _value = CustomValueGetter(); } return _value; } private void SetValue(T value) { if (!object.Equals(_value, value)) { _value = value; CustomValueSetter?.Invoke(value); this.OnValueChanged?.Invoke(value); } } } public class QueueJsonConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(Queue); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { Queue source = (Queue)value; serializer.Serialize(writer, (object)source.ToList()); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { List collection = serializer.Deserialize>(reader); return new Queue(collection); } } } namespace com.github.zehsteam.TwitchTrolling.MonoBehaviours { public enum AudioPlayerType { Default, EnemySpawn } public class AudioPlayer : MonoBehaviour { [CompilerGenerated] private sealed class d__18 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public TimeSpan duration; public AudioPlayer <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown int num = <>1__state; AudioPlayer audioPlayer = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds((float)duration.TotalSeconds); <>1__state = 1; return true; case 1: <>1__state = -1; AudioPlayerFactory.AddToPool(audioPlayer); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const float DefaultVolume = 1f; public const float DefaultMaxDistance = 15f; private AudioSource _audioSource; public AudioPlayerType Type; public Transform TargetTransform; public Vector3 TargetPosition; public AudioSource AudioSource { get { if (_audioSource == null) { _audioSource = ((Component)this).GetComponent(); } return _audioSource; } private set { _audioSource = value; } } public bool IsPlaying { get { AudioSource audioSource = AudioSource; if (audioSource == null) { return false; } return audioSource.isPlaying; } } private void Start() { AudioSource.dopplerLevel = 0f; } private void Update() { UpdatePosition(); UpdateSpatialBlend(); } private void UpdatePosition() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) if ((Object)(object)TargetTransform != (Object)null) { TargetPosition = TargetTransform.position; } ((Component)this).transform.position = TargetPosition; } private void UpdateSpatialBlend() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) float spatialBlend = 1f; PlayerAvatar localPlayer = PlayerHelper.GetLocalPlayer(); if (!((Object)(object)localPlayer == (Object)null)) { float num = Vector3.Distance(((Component)this).transform.position, ((Component)localPlayer.localCamera).transform.position); if (num <= 0.5f) { spatialBlend = 0f; } AudioSource.spatialBlend = spatialBlend; } } public float Play(AudioClip audioClip, Vector3 position, float volume = 1f, float maxDistance = 15f, bool loop = false) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SetTargetPosition(position); return Play(audioClip, volume, maxDistance, loop); } public float Play(AudioClip audioClip, Transform transform, float volume = 1f, float maxDistance = 15f, bool loop = false) { SetTargetTransform(transform); return Play(audioClip, volume, maxDistance, loop); } private float Play(AudioClip audioClip, float volume = 1f, float maxDistance = 15f, bool loop = false) { if ((Object)(object)AudioSource == (Object)null) { if ((Object)(object)((Component)this).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); } return 0f; } if ((Object)(object)audioClip == (Object)null) { AudioPlayerFactory.AddToPool(this); return 0f; } AudioSource.clip = audioClip; AudioSource.volume = volume; AudioSource.maxDistance = maxDistance; AudioSource.loop = loop; if (loop) { if (!AudioSource.isPlaying) { AudioSource.Play(); } } else { AudioSource.PlayOneShot(audioClip, volume); TimeSpan duration = TimeSpan.FromSeconds(audioClip.length + 0.1f); ((MonoBehaviour)this).StartCoroutine(PoolAfterDurationCoroutine(duration)); } return audioClip.length; } [IteratorStateMachine(typeof(d__18))] private IEnumerator PoolAfterDurationCoroutine(TimeSpan duration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__18(0) { <>4__this = this, duration = duration }; } public void Stop() { AudioSource audioSource = AudioSource; if (audioSource != null) { audioSource.Stop(); } } public void SetTargetTransform(Transform targetTransform) { TargetTransform = targetTransform; } public void SetTargetPosition(Vector3 targetPosition) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) TargetTransform = null; TargetPosition = targetPosition; } } public class BrowserLink : MonoBehaviour { [SerializeField] public string _url; public void OpenLink() { Application.OpenURL(_url); } } internal class CoroutineRunner : MonoBehaviour { public static CoroutineRunner Instance { get; private set; } public static CoroutineRunner Spawn() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown if ((Object)(object)Instance != (Object)null) { return Instance; } GameObject val = new GameObject("TwitchTrolling CoroutineRunner", new Type[1] { typeof(CoroutineRunner) }) { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)(object)val); return val.GetComponent(); } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); } else { Instance = this; } } public static Coroutine Start(IEnumerator routine) { if ((Object)(object)Instance == (Object)null) { CoroutineRunner coroutineRunner = Spawn(); return ((coroutineRunner != null) ? ((MonoBehaviour)coroutineRunner).StartCoroutine(routine) : null) ?? null; } CoroutineRunner instance = Instance; return ((instance != null) ? ((MonoBehaviour)instance).StartCoroutine(routine) : null) ?? null; } public static void Stop(IEnumerator routine) { CoroutineRunner instance = Instance; if (instance != null) { ((MonoBehaviour)instance).StopCoroutine(routine); } } public static void Stop(Coroutine routine) { CoroutineRunner instance = Instance; if (instance != null) { ((MonoBehaviour)instance).StopCoroutine(routine); } } } public class DeathMessage : MonoBehaviour { [CompilerGenerated] private sealed class d__26 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public DeathMessage <>4__this; public TimeSpan duration; private float 5__2; private float 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown int num = <>1__state; DeathMessage deathMessage = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; deathMessage._canvasGroup.alpha = 1f; <>2__current = (object)new WaitForSeconds((float)duration.TotalSeconds); <>1__state = 1; return true; case 1: <>1__state = -1; 5__2 = 1f; 5__3 = 0f; break; case 2: <>1__state = -1; 5__3 += Time.deltaTime; break; } if (5__3 < 5__2) { float num2 = 1f / 5__2 * 5__3; float alpha = 1f + -1f * num2; deathMessage._canvasGroup.alpha = alpha; <>2__current = null; <>1__state = 2; return true; } deathMessage._canvasGroup.alpha = 0f; deathMessage._showCoroutine = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [SerializeField] private TextMeshProUGUI _textUGUI; [SerializeField] private Image _backgroundImage; [SerializeField] private CanvasGroup _canvasGroup; private Coroutine _showCoroutine; public static DeathMessage Instance { get; private set; } public static bool IsEnabled => ConfigManager.DeathMessage_Enabled.Value; public static bool ShowPlatformIcon => ConfigManager.DeathMessage_ShowPlatformIcon.Value; public static float Duration => ConfigManager.DeathMessage_Duration.Value; public static float FontSize => ConfigManager.DeathMessage_FontSize.Value; public static int BackgroundTransparency => ConfigManager.DeathMessage_BackgroundTransparency.Value; private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); } else { Instance = this; } } private void Start() { _canvasGroup.alpha = 0f; } public void Show(EnemyParent enemyParent, ViewerData viewerData) { if (!((Object)(object)enemyParent == (Object)null) && viewerData != null) { string text = (ShowPlatformIcon ? "" : string.Empty); string message = ("You died to a " + enemyParent.enemyName + " from " + viewerData.GetDisplayNameWithColor() + " " + text).Trim(); Show(message); } } public void Show(PhysGrabObject physGrabObject, ViewerData viewerData) { if (!((Object)(object)physGrabObject == (Object)null) && viewerData != null) { string text = ((Object)physGrabObject).name.TrimStart("Valuable ").TrimEnd("(Clone)").Trim(); string text2 = (ShowPlatformIcon ? "" : string.Empty); string message = ("You died to a " + text + " from " + viewerData.GetDisplayNameWithColor() + " " + text2).Trim(); Show(message); } } public void ShowForExplosion(ViewerData viewerData, string sourceName = "") { if (viewerData != null) { string text = (ShowPlatformIcon ? "" : string.Empty); string text2 = ((!string.IsNullOrEmpty(sourceName)) ? ("" + sourceName + " (Explosion)") : "explosion"); string message = ("You died to an " + text2 + " from " + viewerData.GetDisplayNameWithColor() + " " + text).Trim(); Show(message); } } public void Show(string message) { Show(message, TimeSpan.FromSeconds(Duration)); } public void Show(string message, TimeSpan duration) { if (IsEnabled) { UseConfigSettings(); if (_showCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_showCoroutine); } ((TMP_Text)_textUGUI).text = message; _showCoroutine = ((MonoBehaviour)this).StartCoroutine(ShowCoroutine(duration)); } } private void UseConfigSettings() { ((TMP_Text)_textUGUI).fontSize = FontSize; _backgroundImage.SetAlpha(BackgroundTransparency); } [IteratorStateMachine(typeof(d__26))] private IEnumerator ShowCoroutine(TimeSpan duration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__26(0) { <>4__this = this, duration = duration }; } } public class EnemyNametag : MonoBehaviour { [SerializeField] private TextMeshProUGUI _usernameText; [SerializeField] public Image _backgroundImage; [SerializeField] public CanvasGroup _canvasGroup; private static readonly float _heightOffset = 0.5f; private static readonly float _minSize = 0.75f; private static readonly float _maxSize = 1.5f; private RectTransform _rectTransform; private Transform _enemyTransform; private object _enemyScript; private bool _continuouslyCalculatePosition; private float _continuouslyCalculatePositionTimer; private float _continuouslyCalculatePositionCooldown = 0.1f; public static List Instances { get; private set; } = new List(); public static bool ShowPlatformIcon => ConfigManager.EnemyNametag_ShowPlatformIcon.Value; public static float SizeMultiplier => ConfigManager.EnemyNametag_SizeMultiplier.Value; public static int BackgroundTransparency => ConfigManager.EnemyNametag_BackgroundTransparency.Value; public EnemyParent EnemyParent { get; private set; } public ViewerData Viewer { get; private set; } private void OnEnable() { Instances.AddSingleInstance(this); } private void OnDisable() { Instances.Remove(this); } public void SetData(EnemyParent enemyParent, ViewerData viewerData) { EnemyParent = enemyParent; Viewer = viewerData; if (IsEnemyTypeElsa()) { _enemyScript = ((Component)enemyParent).GetComponentInChildren(true); _continuouslyCalculatePosition = true; } if (IsEnemyTypeOogly()) { _enemyScript = ((Component)enemyParent).GetComponentInChildren(true); _continuouslyCalculatePosition = true; } } private void Start() { if ((Object)(object)EnemyParent == (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } _rectTransform = ((Component)this).GetComponent(); _enemyTransform = GetEnemyTransform(); bool flag = false; if (IsEnemyTypePeeper()) { flag = true; ((Transform)_rectTransform).SetParent(((Component)EnemyParent.Enemy).transform); } if (!flag) { ((Transform)_rectTransform).SetParent(_enemyTransform); } CalculatePosition(); UseConfigSettings(); } private void Update() { if ((Object)(object)EnemyParent == (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } if (!IsEnemyEnabled()) { _canvasGroup.alpha = 0f; return; } if (IsEnemyTypeHidden()) { Update_HiddenEnemy(); } else { _canvasGroup.alpha = 1f; } if (_continuouslyCalculatePosition) { _continuouslyCalculatePositionTimer += Time.deltaTime; if (_continuouslyCalculatePositionTimer >= _continuouslyCalculatePositionCooldown) { CalculatePosition(); _continuouslyCalculatePositionTimer = 0f; } } } private void Update_HiddenEnemy() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0030: Unknown result type (might be due to invalid IL or missing references) float alpha = 0f; if (TryGetEnemyTransform(out var transform)) { Vector3 origin = transform.position + new Vector3(0f, 1f, 0f); if (PlayerHelper.AnyPlayersNearby(origin, 5f)) { alpha = 1f; } } _canvasGroup.alpha = alpha; } private void LateUpdate() { LookAtLocalCamera(); } private bool IsEnemyTypeHidden() { return EnemyParent.enemyName.Equals("Hidden", StringComparison.OrdinalIgnoreCase); } private bool IsEnemyTypePeeper() { return EnemyParent.enemyName.Equals("Peeper", StringComparison.OrdinalIgnoreCase); } private bool IsEnemyTypeElsa() { return EnemyParent.enemyName.Equals("Elsa", StringComparison.OrdinalIgnoreCase); } private bool IsEnemyTypeOogly() { return EnemyParent.enemyName.Equals("Oogly", StringComparison.OrdinalIgnoreCase); } private bool IsEnemyEnabled() { return EnemyParent.EnableObject.activeSelf; } private Transform GetEnemyTransform() { if ((Object)(object)EnemyParent == (Object)null || (Object)(object)EnemyParent.EnableObject == (Object)null) { return null; } EnemyRigidbody componentInChildren = EnemyParent.EnableObject.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { return ((Component)componentInChildren).transform; } return ((Component)EnemyParent).transform; } private bool TryGetEnemyTransform(out Transform transform) { transform = GetEnemyTransform(); return (Object)(object)transform != (Object)null; } private void LookAtLocalCamera() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar localPlayer = PlayerHelper.GetLocalPlayer(); if (!((Object)(object)localPlayer == (Object)null)) { ((Component)this).transform.LookAt(((Component)this).transform.position + ((Component)localPlayer.localCamera).transform.forward); } } private void CalculatePosition() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0146: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if (IsEnemyTypePeeper()) { ((Transform)_rectTransform).localPosition = new Vector3(0f, 0f, 0.85f); return; } Transform val = _enemyTransform; if (IsEnemyTypeElsa() && _enemyScript != null) { object enemyScript = _enemyScript; EnemyElsa val2 = (EnemyElsa)((enemyScript is EnemyElsa) ? enemyScript : null); if (val2 != null && !val2.IsBig()) { val = val2.smallColliderTransform; } } if (IsEnemyTypeOogly() && _enemyScript != null) { object enemyScript2 = _enemyScript; EnemyOogly val3 = (EnemyOogly)((enemyScript2 is EnemyOogly) ? enemyScript2 : null); if (val3 != null && (Object)(object)val3.targetPlayer == (Object)null) { ((Transform)_rectTransform).localPosition = new Vector3(0f, -1.5f, 0f); return; } } Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren(); if (componentsInChildren == null || componentsInChildren.Length == 0) { Logger.LogWarning("EnemyNametag: No colliders found on the enemy."); return; } float num = float.MinValue; Collider[] array = componentsInChildren; foreach (Collider val4 in array) { if (!val4.isTrigger) { Bounds bounds = val4.bounds; float y = ((Bounds)(ref bounds)).max.y; if (y > num) { num = y; } } } float num2 = num + _heightOffset; Vector3 localPosition = default(Vector3); ((Vector3)(ref localPosition))..ctor(0f, num2 - _enemyTransform.position.y, 0f); ((Transform)_rectTransform).localPosition = localPosition; } public void CalculateScale() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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) Collider[] componentsInChildren = ((Component)_enemyTransform).GetComponentsInChildren(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { Logger.LogWarning("EnemyNametag: No colliders found on the enemy."); return; } Bounds bounds = componentsInChildren[0].bounds; Collider[] array = componentsInChildren; foreach (Collider val in array) { if (!val.isTrigger) { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } Vector3 size = ((Bounds)(ref bounds)).size; float num = ((Vector3)(ref size)).magnitude * 0.5f; num = Mathf.Clamp(num, _minSize, _maxSize); ((Component)this).transform.localScale = Vector3.one * num * SizeMultiplier; } private void UpdateNametagText() { if (Viewer != null) { ((TMP_Text)_usernameText).text = (GetPlatformSpriteText() + " " + Viewer.DisplayName).Trim(); } } public string GetPlatformSpriteText() { if (!ShowPlatformIcon) { return string.Empty; } return ""; } private void SetBackgroundTransparency(int value) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Color32 val = Color32.op_Implicit(((Graphic)_backgroundImage).color); val.a = (byte)Mathf.Clamp(value, 0, 255); ((Graphic)_backgroundImage).color = Color32.op_Implicit(val); } private void UseConfigSettings() { UpdateNametagText(); SetBackgroundTransparency(BackgroundTransparency); CalculateScale(); } public static void OnConfigSettingsChanged() { foreach (EnemyNametag instance in Instances) { instance.UseConfigSettings(); } } } public class IgnoreItemDrone : MonoBehaviour { private PhysGrabObject _physGrabObject; private void Awake() { _physGrabObject = ((Component)this).GetComponent(); if ((Object)(object)_physGrabObject == (Object)null) { Object.Destroy((Object)(object)this); } } private void OnEnable() { if (!((Object)(object)_physGrabObject == (Object)null)) { ItemDronePatch.IgnorePhysGrabObjects.AddSingleInstance(_physGrabObject); } } private void OnDisable() { if (!((Object)(object)_physGrabObject == (Object)null)) { ItemDronePatch.IgnorePhysGrabObjects.Remove(_physGrabObject); } } } public class MessageItem : MonoBehaviour { [CompilerGenerated] private sealed class d__16 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public MessageItem <>4__this; private float 5__2; private float 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown int num = <>1__state; MessageItem messageItem = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; messageItem._canvasGroup.alpha = 1f; <>2__current = (object)new WaitForSeconds(Duration); <>1__state = 1; return true; case 1: <>1__state = -1; 5__2 = 1f; 5__3 = 0f; goto IL_00cc; case 2: <>1__state = -1; 5__3 += Time.deltaTime; goto IL_00cc; case 3: { <>1__state = -1; ((Component)messageItem).gameObject.SetActive(false); messageItem._playAnimationCoroutine = null; return false; } IL_00cc: if (5__3 < 5__2) { float num2 = 1f / 5__2 * 5__3; float alpha = 1f + -1f * num2; messageItem._canvasGroup.alpha = alpha; <>2__current = null; <>1__state = 2; return true; } messageItem._canvasGroup.alpha = 0f; <>2__current = null; <>1__state = 3; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [SerializeField] private TextMeshProUGUI _textUGUI; [SerializeField] private Image _backgroundImage; [SerializeField] private CanvasGroup _canvasGroup; private Coroutine _playAnimationCoroutine; public static List Instances { get; private set; } = new List(); public static float Duration => ConfigManager.Message_Duration.Value; public static float FontSize => ConfigManager.Message_FontSize.Value; public static int BackgroundTransparency => ConfigManager.Message_BackgroundTransparency.Value; private void OnEnable() { Instances.AddSingleInstance(this); UseConfigSettings(); if (_playAnimationCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_playAnimationCoroutine); } _playAnimationCoroutine = ((MonoBehaviour)this).StartCoroutine(PlayAnimationCoroutine()); } private void OnDisable() { Instances.Remove(this); if (_playAnimationCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_playAnimationCoroutine); } } [IteratorStateMachine(typeof(d__16))] private IEnumerator PlayAnimationCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__16(0) { <>4__this = this }; } public void SetText(string message) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) SetText(message, Color.white); } public void SetText(string message, Color color) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)_textUGUI).text = message.Trim(); ((Graphic)_textUGUI).color = color; } private void UseConfigSettings() { ((TMP_Text)_textUGUI).fontSize = FontSize; _backgroundImage.SetAlpha(BackgroundTransparency); } public static void OnConfigSettingsChanged() { foreach (MessageItem instance in Instances) { instance.UseConfigSettings(); } } } public class MessageManager : MonoBehaviour { [SerializeField] private RectTransform _messageListTransform; [SerializeField] public RectTransform _messageItemPrefab; private readonly Queue _pool = new Queue(); private readonly int _poolSize = 30; public static MessageManager Instance { get; private set; } public static bool IsEnabled => ConfigManager.Message_Enabled.Value; private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); } else { Instance = this; } } private void Start() { CreatePool(); } private void CreatePool() { for (int i = 0; i < _poolSize; i++) { RectTransform val = Object.Instantiate(_messageItemPrefab); ((Transform)val).SetParent((Transform)(object)_messageListTransform); ((Component)val).gameObject.SetActive(false); _pool.Enqueue(val); } } public void ShowSpawnEnemyMessage(ViewerSpawnData viewerSpawnData) { string text = ((!string.IsNullOrEmpty(viewerSpawnData.TargetEnemyName)) ? viewerSpawnData.TargetEnemyName : ((viewerSpawnData.TotalSpawnCount <= 1) ? "random enemy" : "random enemies")); string displayNameWithColor = viewerSpawnData.Viewer.GetDisplayNameWithColor(); string message = $"{displayNameWithColor} spawned {viewerSpawnData.TotalSpawnCount}x {text} {viewerSpawnData.SpawnReason}"; ShowMessage(message); } public void ShowExecuteMEventMessage(ViewerData viewerData, MEvent mEvent) { ShowExecuteMEventMessage(viewerData, mEvent, mEvent.BitsPrice.Value); } public void ShowExecuteMEventMessage(ViewerData viewerData, MEvent mEvent, int bitsPaid) { string displayNameWithColor = viewerData.GetDisplayNameWithColor(); string message = $"{displayNameWithColor} triggered {mEvent.Name} by cheering {bitsPaid} bits"; ShowMessage(message); } public void ShowMessage(string message) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) ShowMessage(message, Color.white); } public void ShowMessage(string message, Color color) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (IsEnabled) { SpawnMessageItemFromPool(message, color); } } private RectTransform SpawnMessageItemFromPool(string text, Color color) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (_pool.Count == 0) { Logger.LogError("MessageManager: Failed to spawn MessageItem from pool. MessageItem pool is empty."); return null; } RectTransform val = _pool.Dequeue(); if ((Object)(object)val == (Object)null) { return null; } ((Component)val).gameObject.SetActive(false); ((Component)val).gameObject.SetActive(true); ((Transform)val).SetAsLastSibling(); MessageItem messageItem = default(MessageItem); if (((Component)val).TryGetComponent(ref messageItem)) { messageItem.SetText(text, color); } _pool.Enqueue(val); return val; } } public class PluginHUD : MonoBehaviour { public static PluginHUD Instance { get; private set; } public static void Spawn(Transform parent) { if (!((Object)(object)Instance != (Object)null)) { Object.Instantiate(Assets.PluginHUDPrefab, parent); } } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; ((Object)((Component)this).gameObject).name = "TwitchTrolling HUD"; Logger.LogInfo("Instantiated \"" + ((Object)((Component)this).gameObject).name + "\"", extended: true); } } public class PluginManager : MonoBehaviour { public Transform AudioPlayerContainerTransform; public static PluginManager Instance { get; private set; } public static void Spawn() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Instance != (Object)null)) { GameObject val = Object.Instantiate(Assets.PluginManagerPrefab); val.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); } } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; ((Object)((Component)this).gameObject).name = "TwitchTrolling Manager"; Logger.LogInfo("Instantiated \"" + ((Object)((Component)this).gameObject).name + "\"", extended: true); } } public class TruckProps : MonoBehaviour { [SerializeField] private Transform _modCreditsPositionTransform; public static TruckProps Instance { get; private set; } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; ((Object)((Component)this).gameObject).name = "TwitchTrolling TruckProps"; Logger.LogInfo("Instantiated \"" + ((Object)((Component)this).gameObject).name + "\"", extended: true); } private void Start() { SpawnModCredits(); } private void SpawnModCredits() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0035: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)_modCreditsPositionTransform == (Object)null)) { Vector3 position = _modCreditsPositionTransform.position; Quaternion rotation = _modCreditsPositionTransform.rotation; NetworkPrefabs.SpawnNetworkPrefab(Assets.ModCreditsPrefabRef, position, rotation, (byte)0, (object[])null); } } } } namespace com.github.zehsteam.TwitchTrolling.MEvents { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] public class MEventRegisterAttribute : Attribute { } public static class MEventManager { public static readonly List Events = new List(); public static bool Enabled => ConfigManager.Event_Enabled.Value; public static List EnabledEvents => Events.Where((MEvent x) => x.Enabled.Value).ToList(); public static ConfigFile ConfigFile => ConfigManager.ConfigFile; internal static void Initialize() { IEnumerable enumerable = from type in AccessTools.AllTypes() where type.IsClass && !type.IsAbstract && type.IsSubclassOf(typeof(MEvent)) && type.HasCustomAttribute() select type; foreach (Type item in enumerable) { if (Activator.CreateInstance(item) is MEvent mEvent) { RegisterEvent(mEvent); } } } public static void RegisterEvent(MEvent mEvent) { if (mEvent == null) { Logger.LogError("MEventManager: Failed to register event. MEvent is null."); return; } if (Events.Contains(mEvent)) { Logger.LogError("MEventManager: Failed to register event \"" + mEvent.Name + "\". There is already an event registered with the same name."); return; } mEvent.InitializeInternal(ConfigFile); Events.Add(mEvent); Logger.LogInfo("MEventManager: Registered event \"" + mEvent.Name + "\"", extended: true); } public static bool HasEvents() { return EnabledEvents.Count > 0; } public static bool TryGetEvents(int bitsPrice, out List mEvents) { mEvents = Events.Where((MEvent x) => x.IsMatch(bitsPrice)).ToList(); return mEvents.Count != 0; } public static bool TryGetEvent(int bitsPrice, out MEvent mEvent) { if (!TryGetEvents(bitsPrice, out var mEvents)) { mEvent = null; return false; } mEvent = mEvents[Random.Range(0, mEvents.Count)]; return true; } public static bool TryGetRandomEvent(out MEvent mEvent) { if (EnabledEvents.Count == 0) { mEvent = null; return false; } mEvent = EnabledEvents[Random.Range(0, EnabledEvents.Count)]; return mEvent != null; } public static MEventSFX GetEventSFX(string eventName) { return Assets.MEventSFXList?.GetEventSFX(eventName) ?? null; } public static bool TryGetEventSFX(string eventName, out MEventSFX eventSFX) { eventSFX = GetEventSFX(eventName); return eventSFX != null; } } [Serializable] public class MEventSFX { public string EventName; [FormerlySerializedAs("MainAudioClip")] public AdvancedSFX MainSFX; public AdvancedSFXWithName[] AdditionalSFXList = Array.Empty(); public AudioClip MainAudioClip => MainSFX?.AudioClip ?? null; public AudioClip GetAdditionalAudioClip(string name) { return AdditionalSFXList.FirstOrDefault((AdvancedSFXWithName x) => x.Name.Equals(name, StringComparison.OrdinalIgnoreCase))?.AudioClip ?? null; } public bool TryGetAdditionalAudioClip(string name, out AudioClip audioClip) { audioClip = GetAdditionalAudioClip(name); return (Object)(object)audioClip != (Object)null; } } [Serializable] public class AdvancedSFXWithName : AdvancedSFX { public string Name; } [Serializable] public class AdvancedSFX { [SerializeField] private AudioClip _audioClip; [Range(0f, 3f)] public float VolumeMultiplier = 1f; private readonly Dictionary _cachedAudioClips = new Dictionary(); public AudioClip AudioClip { get { return GetAudioClip(); } set { _audioClip = value; } } public bool HasAudioClip => (Object)(object)AudioClip != (Object)null; public float Length { get { AudioClip audioClip = AudioClip; if (audioClip == null) { return 0f; } return audioClip.length; } } private AudioClip GetAudioClip() { if (VolumeMultiplier == 1f) { return _audioClip; } if (_cachedAudioClips.TryGetValue(VolumeMultiplier, out var value)) { return value; } value = AudioClipUtils.ScaleVolume(_audioClip, VolumeMultiplier); _cachedAudioClips[VolumeMultiplier] = value; return value; } } [CreateAssetMenu(fileName = "MEventSFXList", menuName = "TwitchTrolling/MEventSFXList")] public class MEventSFXList : ScriptableObject { public MEventSFX[] List = Array.Empty(); public MEventSFX GetEventSFX(string eventName) { return List.FirstOrDefault((MEventSFX x) => x.EventName.Equals(eventName, StringComparison.OrdinalIgnoreCase)); } public bool TryGetEventSFX(string eventName, out MEventSFX eventSFX) { eventSFX = GetEventSFX(eventName); return eventSFX != null; } } } namespace com.github.zehsteam.TwitchTrolling.MEvents.Events { [MEventRegister] internal class AggroBeaconEvent : MEvent { [CompilerGenerated] private sealed class d__22 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerAvatar targetPlayerAvatar; public AggroBeaconEvent <>4__this; private Vector3 5__2; private int 5__3; private float 5__4; private float 5__5; private int 5__6; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002d: 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) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown int num = <>1__state; AggroBeaconEvent aggroBeaconEvent = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; 5__2 = ((Component)targetPlayerAvatar).transform.position; float value = aggroBeaconEvent.Duration.Value; 5__3 = aggroBeaconEvent.Pulses.Value; 5__4 = aggroBeaconEvent.Radius.Value; 5__5 = value / (float)5__3; 5__6 = 0; break; } case 1: <>1__state = -1; 5__6++; break; } if (5__6 < 5__3) { EnemyDirector instance = EnemyDirector.instance; if (instance != null) { instance.SetInvestigate(5__2, 5__4, false); } <>2__current = (object)new WaitForSeconds(5__5); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public override string Name => "Aggro Beacon"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 133; public override int DefaultEventSFXVolume => 200; public ConfigEntry Duration { get; private set; } public ConfigEntry Pulses { get; private set; } public ConfigEntry Radius { get; private set; } protected override void RegisterConfigs(ConfigFile configFile) { Duration = configFile.Bind(base.ConfigSection, "Duration", 10f, "", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f)); Pulses = configFile.Bind(base.ConfigSection, "Pulses", 10, "", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100)); Radius = configFile.Bind(base.ConfigSection, "Radius", 100f, "", (AcceptableValueBase)(object)new AcceptableValueRange(10f, 250f)); } protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { StartCoroutine(BeaconCoroutine(targetPlayerAvatar)); } [IteratorStateMachine(typeof(d__22))] private IEnumerator BeaconCoroutine(PlayerAvatar targetPlayerAvatar) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__22(0) { <>4__this = this, targetPlayerAvatar = targetPlayerAvatar }; } protected override int GetSpawnCount() { return -1; } } [MEventRegister] internal class AnimalCrateEvent : MEventPhysTrapDrop { [CompilerGenerated] private sealed class d__19 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AnimalCrateEvent <>4__this; public PhysGrabObject physGrabObject; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; AnimalCrateEvent animalCrateEvent = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = ((MEventPhysTrapDrop)animalCrateEvent).PhysObjectCoroutine(physGrabObject); <>1__state = 1; return true; case 1: { <>1__state = -1; AnimalCrateTrap val = default(AnimalCrateTrap); if (!((Component)physGrabObject).TryGetComponent(ref val)) { return false; } val.TrapActivate(); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private PrefabRef _valuableObjectRef; public override string Name => "Animal Crate"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 257; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 30f; public override int DefaultSpawnCount => 3; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_valuableObjectRef == null) { _valuableObjectRef = ValuableHelper.GetValuableByName("Valuable Manor Animal Crate"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0000: 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_0015: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) position += new Vector3(0f, 2.239f, 1.214f); Quaternion val = Quaternion.Euler(180f, 0f, 0f); return Valuables.SpawnValuable(_valuableObjectRef, position, val); } [IteratorStateMachine(typeof(d__19))] protected override IEnumerator PhysObjectCoroutine(PhysGrabObject physGrabObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__19(0) { <>4__this = this, physGrabObject = physGrabObject }; } } [MEventRegister] internal class BottleEvent : MEventPhysTrapDrop { private PrefabRef _valuableObjectRef; public override string Name => "Bottle"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 111; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 15f; public override int DefaultSpawnCount => 13; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_valuableObjectRef == null) { _valuableObjectRef = ValuableHelper.GetValuableByName("Valuable Manor Bottle"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Valuables.SpawnValuable(_valuableObjectRef, position, Random.rotation); } } [MEventRegister] internal class ChompBookEvent : MEventPhysTrapDrop { private PrefabRef _valuableObjectRef; public override string Name => "Chomp Book"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 233; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 15f; public override int DefaultSpawnCount => 1; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_valuableObjectRef == null) { _valuableObjectRef = ValuableHelper.GetValuableByName("Valuable Wizard Chomp Book"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Valuables.SpawnValuable(_valuableObjectRef, position, Random.rotation); } } [MEventRegister] internal class ClownEvent : MEventPhysObjectDrop { [CompilerGenerated] private sealed class d__20 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PhysGrabObject physGrabObject; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; ClownTrap val = default(ClownTrap); if (!((Component)physGrabObject).TryGetComponent(ref val)) { return false; } val.WarningCount = 0; val.TouchNose(); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private PrefabRef _valuableObjectRef; public override string Name => "Clown"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 254; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 60f; public override int DefaultSpawnCount => 3; public override float DefaultRadius => 2.5f; public override bool DefaultGrabbable => true; public override void Initialize() { base.Initialize(); HasDuration = false; } protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_valuableObjectRef == null) { _valuableObjectRef = ValuableHelper.GetValuableByName("Valuable Manor Clown"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Valuables.SpawnValuable(_valuableObjectRef, position, Random.rotation); } [IteratorStateMachine(typeof(d__20))] protected override IEnumerator PhysObjectCoroutine(PhysGrabObject physGrabObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__20(0) { physGrabObject = physGrabObject }; } } [MEventRegister] internal class DuctTapedGrenadesEvent : MEventPhysItemDrop { [CompilerGenerated] private sealed class d__22 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PhysGrabObject physGrabObject; public DuctTapedGrenadesEvent <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; DuctTapedGrenadesEvent ductTapedGrenadesEvent = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; ItemGrenade val = default(ItemGrenade); if (!((Component)physGrabObject).TryGetComponent(ref val)) { return false; } ductTapedGrenadesEvent.ToggleItem(val.itemToggle, value: true); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Item _item; public override string Name => "Duct Taped Grenades"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 255; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 60f; public override int DefaultSpawnCount => 3; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; public override bool DefaultEquippable => false; public override void Initialize() { base.Initialize(); HasDuration = false; } protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_item == null) { _item = ItemHelper.GetItemByName("Duct Taped Grenades"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Items.SpawnItem(_item, position, Random.rotation); } [IteratorStateMachine(typeof(d__22))] protected override IEnumerator PhysObjectCoroutine(PhysGrabObject physGrabObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__22(0) { <>4__this = this, physGrabObject = physGrabObject }; } } [MEventRegister] internal class DumgolfsStaffEvent : MEventPhysObjectDrop { [CompilerGenerated] private sealed class d__19 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PhysGrabObject physGrabObject; public DumgolfsStaffEvent <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_008d: 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) int num = <>1__state; DumgolfsStaffEvent dumgolfsStaffEvent = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; if ((Object)(object)physGrabObject == (Object)null) { return false; } ValuableWizardStaff val = default(ValuableWizardStaff); if (((Component)physGrabObject).TryGetComponent(ref val)) { float value = dumgolfsStaffEvent.Duration.Value; if (SemiFunc.IsMultiplayer()) { val.photonView.RPC("StaffLaserRPC", (RpcTarget)0, new object[1] { value }); } else { val.StaffLaserRPC(value, default(PhotonMessageInfo)); } } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private PrefabRef _valuableObjectRef; public override string Name => "Dumgolfs Staff"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 263; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 10f; public override int DefaultSpawnCount => 2; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_valuableObjectRef == null) { _valuableObjectRef = ValuableHelper.GetValuableByName("Valuable Wizard Dumgolfs Staff"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(-80f, 0f, Random.Range(0f, 360f)); return Valuables.SpawnValuable(_valuableObjectRef, position, Quaternion.Euler(val)); } [IteratorStateMachine(typeof(d__19))] protected override IEnumerator PhysObjectCoroutine(PhysGrabObject physGrabObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__19(0) { <>4__this = this, physGrabObject = physGrabObject }; } } [MEventRegister] internal class FanEvent : MEventPhysObjectDrop { private class FanTrapBypassIdle : MonoBehaviour { private FanTrap _fanTrap; private void Awake() { _fanTrap = ((Component)this).GetComponent(); } private void OnEnable() { FanTrapPatch.FansToBypassIdle.AddSingleInstance(_fanTrap); } private void OnDisable() { FanTrapPatch.FansToBypassIdle.Remove(_fanTrap); } } [CompilerGenerated] private sealed class d__19 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PhysGrabObject physGrabObject; private FanTrap 5__2; private int 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Invalid comparison between Unknown and I4 //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)physGrabObject == (Object)null) { return false; } if (((Component)physGrabObject).TryGetComponent(ref 5__2)) { ((Component)5__2).gameObject.AddComponent(); <>2__current = null; <>1__state = 2; return true; } break; case 2: <>1__state = -1; 5__2.physgrabobject.grabbed = true; 5__2.StateActive(); 5__3 = 0; goto IL_0122; case 3: { <>1__state = -1; if ((int)5__2.currentState != 1) { 5__2.physgrabobject.grabbed = true; 5__2.stateStart = true; 5__2.currentState = (States)1; 5__2.StateActive(); } 5__3++; goto IL_0122; } IL_0122: if ((float)5__3 < 5f) { <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 3; return true; } break; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private PrefabRef _valuableObjectRef; public override string Name => "Fan"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 126; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 15f; public override int DefaultSpawnCount => 5; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_valuableObjectRef == null) { _valuableObjectRef = ValuableHelper.GetValuableByName("Valuable Arctic Fan"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Valuables.SpawnValuable(_valuableObjectRef, position, Random.rotation); } [IteratorStateMachine(typeof(d__19))] protected override IEnumerator PhysObjectCoroutine(PhysGrabObject physGrabObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__19(0) { physGrabObject = physGrabObject }; } } [MEventRegister] internal class FlamethrowerEvent : MEventPhysObjectDrop { [CompilerGenerated] private sealed class d__19 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PhysGrabObject physGrabObject; public FlamethrowerEvent <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; FlamethrowerEvent flamethrowerEvent = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; if ((Object)(object)physGrabObject == (Object)null) { return false; } FlamethrowerValuable val = default(FlamethrowerValuable); if (((Component)physGrabObject).TryGetComponent(ref val)) { val.fuelTimer = flamethrowerEvent.Duration.Value; val.GrabTrigger(); } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private PrefabRef _valuableObjectRef; public override string Name => "Flamethrower"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 112; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 15f; public override int DefaultSpawnCount => 3; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_valuableObjectRef == null) { _valuableObjectRef = ValuableHelper.GetValuableByName("Valuable Arctic Flamethrower"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Valuables.SpawnValuable(_valuableObjectRef, position, Random.rotation); } [IteratorStateMachine(typeof(d__19))] protected override IEnumerator PhysObjectCoroutine(PhysGrabObject physGrabObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__19(0) { <>4__this = this, physGrabObject = physGrabObject }; } } [MEventRegister] internal class FrogEvent : MEventPhysTrapDrop { private PrefabRef _valuableObjectRef; public override string Name => "Frog"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 113; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 15f; public override int DefaultSpawnCount => 8; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_valuableObjectRef == null) { _valuableObjectRef = ValuableHelper.GetValuableByName("Valuable Manor Frog"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, Random.Range(0f, 360f), 0f); return Valuables.SpawnValuable(_valuableObjectRef, position, Quaternion.Euler(val)); } } [MEventRegister] internal class IceSawEvent : MEventPhysTrapDrop { private PrefabRef _valuableObject; public override string Name => "Ice Saw"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 114; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 15f; public override int DefaultSpawnCount => 3; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_valuableObject == null) { _valuableObject = ValuableHelper.GetValuableByName("Valuable Arctic Ice Saw"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Valuables.SpawnValuable(_valuableObject, position, Random.rotation); } } [MEventRegister] internal class MinefieldEvent : MEventMinefield { [CompilerGenerated] private sealed class d__22 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ItemMine itemMine; public MinefieldEvent <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown int num = <>1__state; MinefieldEvent minefieldEvent = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)itemMine == (Object)null) { return false; } itemMine.physGrabObject.grabDisableTimer = 1000f; Object.Destroy((Object)(object)itemMine.itemEquippable); minefieldEvent.ToggleItem(itemMine.itemToggle, value: true); <>2__current = (object)new WaitForSeconds(minefieldEvent.Duration.Value); <>1__state = 2; return true; case 2: <>1__state = -1; if ((Object)(object)itemMine == (Object)null) { return false; } itemMine.physGrabObject.DestroyPhysGrabObject(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Item _item; public override string Name => "Minefield"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 455; public override int DefaultEventSFXVolume => 200; public override int DefaultMaxSpawnCount => 10; public override float DefaultRadius => 10f; public override float DefaultSpacing => 2.699999f; public ConfigEntry Duration { get; private set; } protected override void RegisterConfigs(ConfigFile configFile) { base.RegisterConfigs(configFile); Duration = configFile.Bind(base.ConfigSection, "Duration", 30f, "", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 300f)); } protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_item == null) { _item = ItemHelper.GetItemByName("Explosive Mine"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) GameObject val = Items.SpawnItem(_item, position, Quaternion.identity); val.AddComponent(); ItemMine itemMine = default(ItemMine); if (val.TryGetComponent(ref itemMine)) { StartCoroutine(ActivateCoroutine(itemMine)); } return val; } [IteratorStateMachine(typeof(d__22))] private IEnumerator ActivateCoroutine(ItemMine itemMine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__22(0) { <>4__this = this, itemMine = itemMine }; } } [MEventRegister] internal class PlayerSpeedEvent : MEvent { [CompilerGenerated] private sealed class d__22 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerSpeedEvent <>4__this; public Transform parentTransform; public TimeSpan duration; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown int num = <>1__state; PlayerSpeedEvent playerSpeedEvent = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; if (playerSpeedEvent.EventSFX == null) { return false; } if (!playerSpeedEvent.EventSFX.TryGetAdditionalAudioClip("Music", out var audioClip)) { return false; } playerSpeedEvent._musicAudioPlayerFactory.Play(audioClip, parentTransform, loop: true); <>2__current = (object)new WaitForSeconds((float)duration.TotalSeconds); <>1__state = 1; return true; } case 1: <>1__state = -1; playerSpeedEvent._musicAudioPlayerFactory.Stop(); playerSpeedEvent._musicCoroutine = null; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private AudioPlayerFactory _musicAudioPlayerFactory; private Coroutine _musicCoroutine; public override string Name => "Player Speed"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 260; public override int DefaultEventSFXVolume => 200; public ConfigEntry SpeedUpgradeLevel { get; private set; } public ConfigEntry Duration { get; private set; } public override void Initialize() { AutoPlayMainAudioClip = false; } protected override void RegisterConfigs(ConfigFile configFile) { SpeedUpgradeLevel = configFile.Bind(base.ConfigSection, "SpeedUpgradeLevel", 20, "", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100)); Duration = configFile.Bind(base.ConfigSection, "Duration", 30f, "", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 300f)); } protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if ((Object)(object)PlayerAvatar.instance != (Object)(object)targetPlayerAvatar) { return; } PlayerControllerPatch.OverrideSpeed(SpeedUpgradeLevel.Value, TimeSpan.FromSeconds(Duration.Value)); if (base.EventSFX == null) { return; } if (_musicAudioPlayerFactory == null) { _musicAudioPlayerFactory = new AudioPlayerFactory { UseMode = AudioPlayerFactory.AudioUseMode.Reuse, Volume = 0.75f }; } if (_musicAudioPlayerFactory.IsPlaying) { PlayMusic(((Component)targetPlayerAvatar.localCamera).transform, TimeSpan.FromSeconds(Duration.Value)); } else if (base.EventSFX.MainSFX != null) { PlayMainAudioClip(targetPlayerAvatar); StartCoroutine(Utils.InvokeAfterDurationCoroutine(TimeSpan.FromSeconds(base.EventSFX.MainSFX.Length), delegate { PlayMusic(((Component)targetPlayerAvatar.localCamera).transform, TimeSpan.FromSeconds(Duration.Value - base.EventSFX.MainSFX.Length)); })); } } private void PlayMusic(Transform parentTransform, TimeSpan duration) { if (_musicCoroutine != null) { StopCoroutine(_musicCoroutine); } _musicCoroutine = StartCoroutine(PlayMusicCoroutine(parentTransform, duration)); } [IteratorStateMachine(typeof(d__22))] private IEnumerator PlayMusicCoroutine(Transform parentTransform, TimeSpan duration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__22(0) { <>4__this = this, parentTransform = parentTransform, duration = duration }; } protected override int GetSpawnCount() { return -1; } } [MEventRegister] internal class PropaneTankEvent : MEventPhysTrapDrop { private PrefabRef _valuableObjectRef; public override string Name => "Propane Tank"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 204; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 15f; public override int DefaultSpawnCount => 5; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_valuableObjectRef == null) { _valuableObjectRef = ValuableHelper.GetValuableByName("Valuable Arctic Propane Tank"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Valuables.SpawnValuable(_valuableObjectRef, position, Random.rotation); } } [MEventRegister] internal class PsychoEvent : MEventPhysTrapDrop { private PrefabRef _valuableObjectRef; public override string Name => "Psycho"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 69; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 30f; public override int DefaultSpawnCount => 1; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_valuableObjectRef == null) { _valuableObjectRef = ValuableHelper.GetValuableByName("Valuable Psycho"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, Random.Range(0f, 360f), 0f); return Valuables.SpawnValuable(_valuableObjectRef, position, Quaternion.Euler(val)); } } [MEventRegister] internal class RollDroneEvent : MEventMinefield { [CompilerGenerated] private sealed class d__23 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ItemDrone itemDrone; public RollDroneEvent <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__23(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown int num = <>1__state; RollDroneEvent rollDroneEvent = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; if ((Object)(object)itemDrone == (Object)null) { return false; } itemDrone.itemBattery.isUnchargable = true; ItemBattery itemBattery = itemDrone.itemBattery; itemBattery.batteryLife *= 100f; ItemBattery itemBattery2 = itemDrone.itemBattery; itemBattery2.batteryLifeInt *= 100; itemDrone.physGrabObject.grabDisableTimer = 1000f; Object.Destroy((Object)(object)itemDrone.itemEquippable); rollDroneEvent.ToggleItem(itemDrone.itemToggle, value: true); <>2__current = (object)new WaitForSeconds(rollDroneEvent.Duration.Value); <>1__state = 2; return true; } case 2: <>1__state = -1; if ((Object)(object)itemDrone == (Object)null) { return false; } itemDrone.physGrabObject.DestroyPhysGrabObject(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Item _item; public override string Name => "Roll Drone"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 259; public override int DefaultEventSFXVolume => 200; public override int DefaultMaxSpawnCount => 20; public override float DefaultRadius => 10f; public override float DefaultSpacing => 2.5f; public ConfigEntry Duration { get; private set; } public override void Initialize() { MinDistanceFromPlayer = 0f; } protected override void RegisterConfigs(ConfigFile configFile) { base.RegisterConfigs(configFile); Duration = configFile.Bind(base.ConfigSection, "Duration", 30f, "", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 300f)); } protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_item == null) { _item = ItemHelper.GetItemByName("Roll Drone"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) GameObject val = Items.SpawnItem(_item, position, Random.rotation); ItemDrone itemDrone = default(ItemDrone); if (val.TryGetComponent(ref itemDrone)) { StartCoroutine(ActivateCoroutine(itemDrone)); } return val; } [IteratorStateMachine(typeof(d__23))] private IEnumerator ActivateCoroutine(ItemDrone itemDrone) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__23(0) { <>4__this = this, itemDrone = itemDrone }; } } [MEventRegister] internal class RubberDuckEvent : MEventPhysItemDrop { public class ItemRubberDuckSpecial : MonoBehaviour { private ItemRubberDuck _itemRubberDuck; private void Awake() { _itemRubberDuck = ((Component)this).GetComponent(); if ((Object)(object)_itemRubberDuck == (Object)null) { Object.Destroy((Object)(object)this); } } private void OnEnable() { ItemRubberDuckPatch.SpecialRubberDucks.AddSingleInstance(_itemRubberDuck); } private void OnDisable() { ItemRubberDuckPatch.SpecialRubberDucks.Remove(_itemRubberDuck); } } [CompilerGenerated] private sealed class d__30 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PhysGrabObject physGrabObject; public RubberDuckEvent <>4__this; private ItemRubberDuck 5__2; private Rigidbody 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__30(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; RubberDuckEvent rubberDuckEvent = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if (!((Component)physGrabObject).TryGetComponent(ref 5__2)) { return false; } 5__2.itemBattery.isUnchargable = true; <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = (object)new WaitForFixedUpdate(); <>1__state = 3; return true; case 3: { <>1__state = -1; if ((Object)(object)5__2 == (Object)null) { return false; } float value2 = rubberDuckEvent.InitialForce.Value; 5__3 = 5__2.rb; Vector3 onUnitSphere = Random.onUnitSphere; 5__3.AddForce(onUnitSphere * value2, (ForceMode)1); goto IL_00ef; } case 4: { <>1__state = -1; if (!((Object)(object)5__3 == (Object)null)) { float value = rubberDuckEvent.MinVelocity.Value; Vector3 velocity = 5__3.velocity; float magnitude = ((Vector3)(ref velocity)).magnitude; if (magnitude < value) { Rigidbody obj = 5__3; obj.velocity *= value - magnitude; } goto IL_00ef; } return false; } IL_00ef: <>2__current = (object)new WaitForFixedUpdate(); <>1__state = 4; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Item _item; public override string Name => "Rubber Duck"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 256; public override int DefaultEventSFXVolume => 200; public override float DefaultDuration => 30f; public override int DefaultSpawnCount => 5; public override float DefaultRadius => 3f; public override bool DefaultGrabbable => true; public override bool DefaultEquippable => false; public ConfigEntry InitialForce { get; private set; } public ConfigEntry MinVelocity { get; private set; } protected override void RegisterConfigs(ConfigFile configFile) { base.RegisterConfigs(configFile); InitialForce = configFile.Bind(base.ConfigSection, "InitialForce", 35f, "", (AcceptableValueBase)(object)new AcceptableValueRange(10f, 200f)); MinVelocity = configFile.Bind(base.ConfigSection, "MinVelocity", 10f, "", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f)); } protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { if (_item == null) { _item = ItemHelper.GetItemByName("Rubber Duck"); } base.Execute(viewerData, targetPlayerAvatar); } public override GameObject SpawnPhysObject(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) GameObject val = Items.SpawnItem(_item, position, Random.rotation); val.AddComponent(); return val; } [IteratorStateMachine(typeof(d__30))] protected override IEnumerator PhysObjectCoroutine(PhysGrabObject physGrabObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__30(0) { <>4__this = this, physGrabObject = physGrabObject }; } } [MEventRegister] internal class ZeroGravityOrbEvent : MEvent { public class ZeroGravityOrbLevitation : MonoBehaviour { [CompilerGenerated] private sealed class d__19 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PhysGrabObject physGrabObject; public ZeroGravityOrbLevitation <>4__this; private float 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown int num = <>1__state; ZeroGravityOrbLevitation zeroGravityOrbLevitation = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; 5__2 += Time.fixedDeltaTime; if ((Object)(object)physGrabObject == (Object)null || !zeroGravityOrbLevitation._physGrabObjects.Contains(physGrabObject)) { goto IL_00a3; } zeroGravityOrbLevitation.LevitatePhysObject(physGrabObject); } else { <>1__state = -1; if ((Object)(object)physGrabObject == (Object)null) { return false; } 5__2 = 0f; } if (5__2 < zeroGravityOrbLevitation.Duration) { <>2__current = (object)new WaitForFixedUpdate(); <>1__state = 1; return true; } goto IL_00a3; IL_00a3: return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__16 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerAvatar playerAvatar; public ZeroGravityOrbLevitation <>4__this; private float 5__2; private Rigidbody 5__3; private float 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown int num = <>1__state; ZeroGravityOrbLevitation zeroGravityOrbLevitation = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (!playerAvatar.isLocal || (Object)(object)PlayerController.instance == (Object)null) { return false; } 5__2 = zeroGravityOrbLevitation.Force * zeroGravityOrbLevitation._playerForceMultiplier * 3f; <>2__current = (object)new WaitForFixedUpdate(); <>1__state = 1; return true; case 1: <>1__state = -1; 5__3 = PlayerController.instance.rb; 5__4 = 0f; goto IL_010e; case 2: { <>1__state = -1; 5__4 += Time.fixedDeltaTime; if ((Object)(object)5__3 == (Object)null || !zeroGravityOrbLevitation._playerAvatars.Contains(playerAvatar)) { break; } PlayerControllerPatch.OverrideGravity(0f, TimeSpan.FromSeconds(0.10000000149011612)); zeroGravityOrbLevitation.LevitateRigidbody(5__3, 5__2); goto IL_010e; } IL_010e: if (5__4 < zeroGravityOrbLevitation.Duration) { <>2__current = (object)new WaitForFixedUpdate(); <>1__state = 2; return true; } break; } PlayerControllerPatch.OverrideGravity(0f, TimeSpan.FromSeconds(1.5)); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const float DefaultDuration = 4f; public const float DefaultForce = 10f; public const bool DefaultTumblePlayer = true; public const float DefaultEnemyStunDuration = 5f; public float Duration = 4f; public float Force = 10f; public bool TumblePlayer = true; public float EnemyStunDuration = 5f; private List _playerAvatars = new List(); private List _physGrabObjects = new List(); private ItemOrb _itemOrb; private float _playerForceMultiplier = 3f; private void Start() { _itemOrb = ((Component)this).GetComponent(); } private void FixedUpdate() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (_itemOrb.itemActive) { UpdateTargetsInRange(((Component)this).transform.position, _itemOrb.orbRadius); } } private void UpdateTargetsInRange(Vector3 position, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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) List list = SemiFunc.PlayerGetAllPlayerAvatarWithinRange(radius, position, false, default(LayerMask)); List list2 = SemiFunc.PhysGrabObjectGetAllWithinRange(radius, position, false, default(LayerMask), (PhysGrabObject)null); _playerAvatars.RemoveAll(_playerAvatars.GetMissingFrom(list)); _physGrabObjects.RemoveAll(_physGrabObjects.GetMissingFrom(list2)); foreach (PlayerAvatar item in list) { if (_playerAvatars.AddSingleInstance(item)) { HandleTargetInRange(item); } } foreach (PhysGrabObject item2 in list2) { if (_physGrabObjects.AddSingleInstance(item2)) { HandleTargetInRange(item2); } } } private void HandleTargetInRange(PlayerAvatar playerAvatar) { if (TumblePlayer) { PlayerHelper.PlayerTumble(playerAvatar); } else { ((MonoBehaviour)this).StartCoroutine(LevitatePlayerCoroutine(playerAvatar)); } } [IteratorStateMachine(typeof(d__16))] private IEnumerator LevitatePlayerCoroutine(PlayerAvatar playerAvatar) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__16(0) { <>4__this = this, playerAvatar = playerAvatar }; } private void HandleTargetInRange(PhysGrabObject physGrabObject) { ((MonoBehaviour)this).StartCoroutine(LevitatePhysObjectCoroutine(physGrabObject)); if (EnemyStunDuration > 0f) { StunEnemy(physGrabObject); } } private void StunEnemy(PhysGrabObject physGrabObject) { EnemyRigidbody val = default(EnemyRigidbody); if (!((Object)(object)physGrabObject == (Object)null) && physGrabObject.isEnemy && ((Component)physGrabObject).TryGetComponent(ref val)) { Enemy enemy = val.enemy; EnemyDuck item = default(EnemyDuck); if (((Component)enemy).TryGetComponent(ref item)) { EnemyDuckPatch.DucksToBypassStunAggroOnce.AddSingleInstance(item); } enemy.StateStunned.Set(EnemyStunDuration); } } [IteratorStateMachine(typeof(d__19))] private IEnumerator LevitatePhysObjectCoroutine(PhysGrabObject physGrabObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__19(0) { <>4__this = this, physGrabObject = physGrabObject }; } private void LevitatePhysObject(PhysGrabObject physGrabObject) { if (!((Object)(object)physGrabObject == (Object)null)) { float num = Force; PlayerTumble val = default(PlayerTumble); if (((Component)physGrabObject).TryGetComponent(ref val)) { num *= _playerForceMultiplier; } LevitateRigidbody(physGrabObject.rb, num); } } private void LevitateRigidbody(Rigidbody rigidbody, float force) { //IL_0013: 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) //IL_0023: 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_0039: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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) if (!((Object)(object)rigidbody == (Object)null) && !rigidbody.isKinematic) { rigidbody.AddForce(Vector3.up * Time.fixedDeltaTime * force, (ForceMode)0); rigidbody.AddTorque(Vector3.up * Time.fixedDeltaTime * 0.2f, (ForceMode)0); rigidbody.AddTorque(Vector3.left * Time.fixedDeltaTime * 0.1f, (ForceMode)0); rigidbody.velocity = Vector3.Lerp(rigidbody.velocity, new Vector3(0f, rigidbody.velocity.y, 0f), Time.fixedDeltaTime * 2f); } } } [CompilerGenerated] private sealed class d__42 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ItemOrb itemOrb; public ZeroGravityOrbEvent <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__42(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown int num = <>1__state; ZeroGravityOrbEvent zeroGravityOrbEvent = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; itemOrb.orbRadius = zeroGravityOrbEvent.Radius.Value; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; if ((Object)(object)itemOrb == (Object)null) { return false; } itemOrb.itemBattery.isUnchargable = true; ItemBattery itemBattery = itemOrb.itemBattery; itemBattery.batteryLife *= 100f; ItemBattery itemBattery2 = itemOrb.itemBattery; itemBattery2.batteryLifeInt *= 100; itemOrb.physGrabObject.grabDisableTimer = 1000f; Object.Destroy((Object)(object)itemOrb.itemEquippable); zeroGravityOrbEvent.ToggleItem(itemOrb.itemToggle, value: true); if (zeroGravityOrbEvent.Levitation.Value) { ZeroGravityOrbLevitation zeroGravityOrbLevitation = ((Component)itemOrb).gameObject.AddComponent(); zeroGravityOrbLevitation.Duration = zeroGravityOrbEvent.LevitationDuration.Value; zeroGravityOrbLevitation.Force = zeroGravityOrbEvent.LevitationForce.Value; zeroGravityOrbLevitation.TumblePlayer = zeroGravityOrbEvent.LevitationTumblePlayer.Value; zeroGravityOrbLevitation.EnemyStunDuration = zeroGravityOrbEvent.LevitationEnemyStunDuration.Value; } <>2__current = (object)new WaitForSeconds(zeroGravityOrbEvent.Duration.Value); <>1__state = 2; return true; } case 2: <>1__state = -1; if ((Object)(object)itemOrb == (Object)null) { return false; } itemOrb.physGrabObject.DestroyPhysGrabObject(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__44 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ZeroGravityOrbEvent <>4__this; public Transform parentTransform; public TimeSpan duration; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__44(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown int num = <>1__state; ZeroGravityOrbEvent zeroGravityOrbEvent = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; if (zeroGravityOrbEvent.EventSFX == null) { return false; } if (!zeroGravityOrbEvent.EventSFX.TryGetAdditionalAudioClip("Music", out var audioClip)) { return false; } zeroGravityOrbEvent._musicAudioPlayerFactory.MaxDistance = Mathf.Max(zeroGravityOrbEvent.Radius.Value + 10f, 15f); zeroGravityOrbEvent._musicAudioPlayerFactory.Play(audioClip, parentTransform, loop: true); <>2__current = (object)new WaitForSeconds((float)duration.TotalSeconds); <>1__state = 1; return true; } case 1: <>1__state = -1; zeroGravityOrbEvent._musicAudioPlayerFactory.Stop(); zeroGravityOrbEvent._musicCoroutine = null; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Item _item; private AudioPlayerFactory _musicAudioPlayerFactory; private Coroutine _musicCoroutine; public override string Name => "Zero Gravity Orb"; public override bool EnabledByDefault => true; public override int DefaultBitsPrice => 195; public override int DefaultEventSFXVolume => 200; public ConfigEntry Duration { get; private set; } public ConfigEntry Radius { get; private set; } public ConfigEntry Levitation { get; private set; } public ConfigEntry LevitationDuration { get; private set; } public ConfigEntry LevitationForce { get; private set; } public ConfigEntry LevitationTumblePlayer { get; private set; } public ConfigEntry LevitationEnemyStunDuration { get; private set; } public override void Initialize() { AutoPlayMainAudioClip = false; } protected override void RegisterConfigs(ConfigFile configFile) { Duration = configFile.Bind(base.ConfigSection, "Duration", 30f, "", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 300f)); Radius = configFile.Bind(base.ConfigSection, "Radius", 10f, "", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 50f)); Levitation = configFile.Bind(base.ConfigSection, "Levitation", true, ""); LevitationDuration = configFile.Bind(base.ConfigSection, "LevitationDuration", 4f, "", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 60f)); LevitationForce = configFile.Bind(base.ConfigSection, "LevitationForce", 10f, "", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 100f)); LevitationTumblePlayer = configFile.Bind(base.ConfigSection, "LevitationTumblePlayer", true, ""); LevitationEnemyStunDuration = configFile.Bind(base.ConfigSection, "LevitationEnemyStunDuration", 5f, "", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 60f)); } protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { //IL_002d: 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) //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_0046: 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) if (_item == null) { _item = ItemHelper.GetItemByName("Zero Gravity Orb"); } Transform transform = ((Component)targetPlayerAvatar).transform; Vector3 val = transform.position + Vector3.up * 0.25f; GameObject gameObject = Items.SpawnItem(_item, val, Random.rotation); ItemOrb itemOrb = default(ItemOrb); if (gameObject.TryGetComponent(ref itemOrb)) { StartCoroutine(ActivateCoroutine(itemOrb)); } if (base.EventSFX == null) { return; } if (_musicAudioPlayerFactory == null) { _musicAudioPlayerFactory = new AudioPlayerFactory { UseMode = AudioPlayerFactory.AudioUseMode.Reuse, Volume = 0.75f }; } if (_musicAudioPlayerFactory.IsPlaying) { PlayMusic(gameObject.transform, TimeSpan.FromSeconds(Duration.Value)); } else if (base.EventSFX.MainSFX != null) { PlayMainAudioClip(targetPlayerAvatar); StartCoroutine(Utils.InvokeAfterDurationCoroutine(TimeSpan.FromSeconds(base.EventSFX.MainSFX.Length), delegate { PlayMusic(gameObject.transform, TimeSpan.FromSeconds(Duration.Value - base.EventSFX.MainSFX.Length)); })); } } [IteratorStateMachine(typeof(d__42))] private IEnumerator ActivateCoroutine(ItemOrb itemOrb) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__42(0) { <>4__this = this, itemOrb = itemOrb }; } private void PlayMusic(Transform parentTransform, TimeSpan duration) { if (_musicCoroutine != null) { StopCoroutine(_musicCoroutine); } _musicCoroutine = StartCoroutine(PlayMusicCoroutine(parentTransform, duration)); } [IteratorStateMachine(typeof(d__44))] private IEnumerator PlayMusicCoroutine(Transform parentTransform, TimeSpan duration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__44(0) { <>4__this = this, parentTransform = parentTransform, duration = duration }; } protected override int GetSpawnCount() { return 1; } } } namespace com.github.zehsteam.TwitchTrolling.MEvents.BaseEvents { public abstract class MEvent { private MEventSFX _eventSFX; protected AudioPlayerFactory AudioPlayerFactory; protected float Volume = 1f; protected bool AutoPlayMainAudioClip = true; public abstract string Name { get; } public abstract bool EnabledByDefault { get; } public abstract int DefaultBitsPrice { get; } public abstract int DefaultEventSFXVolume { get; } public string ConfigSection => "Event: " + Name; public ConfigEntry Enabled { get; private set; } public ConfigEntry BitsPrice { get; private set; } public ConfigEntry EventSFXVolume { get; private set; } protected MEventSFX EventSFX { get { if (_eventSFX == null) { _eventSFX = GetEventSFX(); } return _eventSFX; } private set { _eventSFX = value; } } public bool IsMatch(int bitsPrice) { if (!Enabled.Value) { return false; } return BitsPrice.Value == bitsPrice; } internal void InitializeInternal(ConfigFile configFile) { Enabled = configFile.Bind(ConfigSection, "Enabled", EnabledByDefault, "Enable or disable this event."); BitsPrice = configFile.Bind(ConfigSection, "BitsPrice", DefaultBitsPrice, "Bits required to trigger this event.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 1000)); EventSFXVolume = configFile.Bind(ConfigSection, "EventSFXVolume", DefaultEventSFXVolume, "The volume of the event sfx.", (AcceptableValueBase)(object)new AcceptableValueRange(100, 500)); Enabled.SettingChanged += delegate { PageManager.UpdatePage(); }; BitsPrice.SettingChanged += delegate { PageManager.UpdatePage(); }; EventSFXVolume.SettingChanged += delegate { HandleEventSFXVolumeChanged(); }; HandleEventSFXVolumeChanged(); Initialize(); RegisterConfigs(configFile); } public virtual void Initialize() { } protected virtual void RegisterConfigs(ConfigFile configFile) { } public bool ExecuteEvent(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { return ExecuteEvent(viewerData, targetPlayerAvatar, BitsPrice.Value); } public bool ExecuteEvent(ViewerData viewerData, PlayerAvatar targetPlayerAvatar, int bitsPaid) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) try { if (!SemiFunc.IsMasterClientOrSingleplayer()) { throw new UnauthorizedAccessException("Only the master client (host) can execute events."); } if (AudioPlayerFactory == null) { AudioPlayerFactory = CreateAudioPlayerFactory(); } Execute(viewerData, targetPlayerAvatar); if (AutoPlayMainAudioClip) { PlayMainAudioClip(targetPlayerAvatar); } MessageManager.Instance?.ShowExecuteMEventMessage(viewerData, this, bitsPaid); return true; } catch (Exception arg) { Logger.LogError($"MEvent: Failed to trigger event {Name}. {arg}"); MessageManager.Instance?.ShowMessage("Failed to trigger event " + Name, Color.red); return false; } } protected abstract void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar); protected void PlayMainAudioClip(PlayerAvatar targetPlayerAvatar) { if (EventSFX == null) { return; } AudioClip mainAudioClip = EventSFX.MainAudioClip; if (!((Object)(object)mainAudioClip == (Object)null)) { if (AudioPlayerFactory == null) { AudioPlayerFactory = CreateAudioPlayerFactory(); } AudioPlayerFactory.Play(mainAudioClip, ((Component)targetPlayerAvatar.localCamera).transform); } } protected virtual MEventSFX GetEventSFX() { return MEventManager.GetEventSFX(Name); } protected virtual AudioPlayerFactory CreateAudioPlayerFactory() { return new AudioPlayerFactory { Volume = Volume }; } private void HandleEventSFXVolumeChanged() { if (EventSFX != null && EventSFX.MainSFX != null) { EventSFX.MainSFX.VolumeMultiplier = (float)EventSFXVolume.Value * 0.01f; } } protected abstract int GetSpawnCount(); public virtual JObject GetCardJSON() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0037: Expected O, but got Unknown JObject val = new JObject { ["name"] = JToken.op_Implicit(Name), ["price"] = JToken.op_Implicit(BitsPrice.Value) }; int spawnCount = GetSpawnCount(); if (spawnCount > 0) { val.Add("spawnCount", JToken.op_Implicit(spawnCount)); } return val; } protected Coroutine StartCoroutine(IEnumerator routine) { PluginManager instance = PluginManager.Instance; return ((instance != null) ? ((MonoBehaviour)instance).StartCoroutine(routine) : null) ?? null; } protected void StopCoroutine(Coroutine routine) { PluginManager instance = PluginManager.Instance; if (instance != null) { ((MonoBehaviour)instance).StopCoroutine(routine); } } protected void ToggleItem(ItemToggle itemToggle, bool value) { if (!((Object)(object)itemToggle == (Object)null)) { int num = -1; if ((Object)(object)PlayerAvatar.instance != (Object)null && (Object)(object)PlayerAvatar.instance.photonView != (Object)null) { num = PlayerAvatar.instance.photonView.ViewID; } itemToggle.ToggleItem(value, num); } } } public abstract class MEventMinefield : MEvent { protected float MinDistanceFromPlayer = 2f; public abstract int DefaultMaxSpawnCount { get; } public abstract float DefaultRadius { get; } public abstract float DefaultSpacing { get; } public ConfigEntry MaxSpawnCount { get; private set; } public ConfigEntry Spacing { get; private set; } protected override void RegisterConfigs(ConfigFile configFile) { MaxSpawnCount = configFile.Bind(base.ConfigSection, "MaxSpawnCount", DefaultMaxSpawnCount, "", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100)); Spacing = configFile.Bind(base.ConfigSection, "Spacing", DefaultSpacing, "", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 5f)); MaxSpawnCount.SettingChanged += delegate { PageManager.UpdatePage(); }; } protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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) if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } Transform transform = ((Component)targetPlayerAvatar).transform; Vector3 center = transform.position + Vector3.up * 1f; float value = Spacing.Value; List list = GridUtils.GenerateGridAroundPosition(center, 20f, value, MinDistanceFromPlayer); Logger.LogDebug($"MEventMinefield: Points count {list.Count}"); if (list.Count == 0) { throw new Exception("Could not find any spawn points."); } int value2 = MaxSpawnCount.Value; int num = 0; while (num < value2 && list.Count != 0) { Vector3 val = list[0]; list.RemoveAt(0); bool flag = true; for (int i = 0; i <= 6; i++) { if (!HasObjectInsidePoint(val)) { flag = false; break; } val += Vector3.up * 0.5f; } if (!flag && HasGroundBelowPoint(val) && !HasHurtColliderBelowPoint(val)) { SpawnPhysObject(val).SetViewerMetadata(viewerData); num++; } } if (num == 0) { throw new Exception("Could not spawn any objects."); } Logger.LogDebug($"MEventMinefield: Spawned {num} of {value2} objects."); } private bool HasObjectInsidePoint(Vector3 position, float radius = 0.15f) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return Physics.CheckSphere(position, radius, LayerMask.GetMask(new string[1] { "Default" }), (QueryTriggerInteraction)1); } private bool HasGroundBelowPoint(Vector3 position, float maxDistance = 20f) { //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) return Physics.Raycast(position, Vector3.down, maxDistance, LayerMask.GetMask(new string[1] { "Default" }), (QueryTriggerInteraction)1); } private bool HasHurtColliderBelowPoint(Vector3 position, float maxDistance = 20f) { //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) RaycastHit val = default(RaycastHit); HurtCollider val2 = default(HurtCollider); if (Physics.Raycast(position, Vector3.down, ref val, maxDistance, LayerMask.GetMask(new string[2] { "Default", "Triggers" }), (QueryTriggerInteraction)2)) { return ((Component)((RaycastHit)(ref val)).collider).TryGetComponent(ref val2); } return false; } public abstract GameObject SpawnPhysObject(Vector3 position); protected override int GetSpawnCount() { return MaxSpawnCount.Value; } } public abstract class MEventPhysItemDrop : MEventPhysObjectDrop { [CompilerGenerated] private sealed class d__8 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public MEventPhysItemDrop <>4__this; public PhysGrabObject physGrabObject; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; MEventPhysItemDrop mEventPhysItemDrop = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = ((MEventPhysObjectDrop)mEventPhysItemDrop).SetPropertiesCoroutine(physGrabObject); <>1__state = 1; return true; case 1: { <>1__state = -1; bool flag = mEventPhysItemDrop.Toggleable; ItemEquippable val = default(ItemEquippable); if (mEventPhysItemDrop.Equippable.Value) { flag = true; } else if (((Component)physGrabObject).TryGetComponent(ref val)) { Object.Destroy((Object)(object)val); } ItemToggle val2 = default(ItemToggle); if (!flag && ((Component)physGrabObject).TryGetComponent(ref val2)) { ((Behaviour)val2).enabled = false; } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } protected bool Toggleable; public abstract bool DefaultEquippable { get; } public ConfigEntry Equippable { get; private set; } protected override void RegisterConfigs(ConfigFile configFile) { base.RegisterConfigs(configFile); Equippable = configFile.Bind(base.ConfigSection, "Equippable", DefaultEquippable, ""); } [IteratorStateMachine(typeof(d__8))] internal override IEnumerator SetPropertiesCoroutine(PhysGrabObject physGrabObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__8(0) { <>4__this = this, physGrabObject = physGrabObject }; } } public abstract class MEventPhysObjectDrop : MEvent { [CompilerGenerated] private sealed class d__29 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GameObject gameObject; public MEventPhysObjectDrop <>4__this; private PhysGrabObject 5__2; private Coroutine 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__29(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown int num = <>1__state; MEventPhysObjectDrop mEventPhysObjectDrop = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; if (!gameObject.TryGetComponent(ref 5__2)) { return false; } 5__3 = mEventPhysObjectDrop.StartCoroutine(mEventPhysObjectDrop.PhysObjectCoroutine(5__2)); mEventPhysObjectDrop.StartCoroutine(mEventPhysObjectDrop.SetPropertiesCoroutine(5__2)); float num2 = (mEventPhysObjectDrop.HasDuration ? mEventPhysObjectDrop.Duration.Value : 10000f); <>2__current = (object)new WaitForSeconds(num2); <>1__state = 1; return true; } case 1: <>1__state = -1; if (5__3 != null) { mEventPhysObjectDrop.StopCoroutine(5__3); } if ((Object)(object)5__2 != (Object)null) { mEventPhysObjectDrop.DestroyPhysObject(5__2); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__31 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PhysGrabObject physGrabObject; public MEventPhysObjectDrop <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__31(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; MEventPhysObjectDrop mEventPhysObjectDrop = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)physGrabObject == (Object)null) { return false; } if (!mEventPhysObjectDrop.Grabbable.Value) { physGrabObject.grabDisableTimer = 10000f; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } protected bool HasDuration = true; protected float YOffset = 1f; public abstract float DefaultDuration { get; } public abstract int DefaultSpawnCount { get; } public abstract float DefaultRadius { get; } public abstract bool DefaultGrabbable { get; } public ConfigEntry Duration { get; private set; } public ConfigEntry SpawnCount { get; private set; } public ConfigEntry Radius { get; private set; } public ConfigEntry Grabbable { get; private set; } protected override void RegisterConfigs(ConfigFile configFile) { if (HasDuration) { Duration = configFile.Bind(base.ConfigSection, "Duration", DefaultDuration, "", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 300f)); } SpawnCount = configFile.Bind(base.ConfigSection, "SpawnCount", DefaultSpawnCount, "", (AcceptableValueBase)(object)new AcceptableValueRange(1, 20)); Radius = configFile.Bind(base.ConfigSection, "Radius", DefaultRadius, "", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 10f)); Grabbable = configFile.Bind(base.ConfigSection, "Grabbable", DefaultGrabbable, ""); SpawnCount.SettingChanged += delegate { PageManager.UpdatePage(); }; } protected override void Execute(ViewerData viewerData, PlayerAvatar targetPlayerAvatar) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_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_004e: 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) //IL_0093: 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) //IL_009d: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer()) { Transform transform = ((Component)targetPlayerAvatar).transform; int value = SpawnCount.Value; float value2 = Radius.Value; float num = 360f / (float)value; Vector3 val = transform.position + Vector3.up * YOffset; float y = transform.eulerAngles.y; Vector3 val2 = default(Vector3); for (int i = 0; i < value; i++) { float num2 = y + (float)i * num; float num3 = num2 * (MathF.PI / 180f); ((Vector3)(ref val2))..ctor(Mathf.Sin(num3) * value2, 0f, Mathf.Cos(num3) * value2); Vector3 position = val + val2; GameObject gameObject = SpawnPhysObject(position); gameObject.SetViewerMetadata(viewerData); StartCoroutine(MainPhysObjectCoroutine(gameObject)); } } } public abstract GameObject SpawnPhysObject(Vector3 position); [IteratorStateMachine(typeof(d__29))] private IEnumerator MainPhysObjectCoroutine(GameObject gameObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__29(0) { <>4__this = this, gameObject = gameObject }; } protected abstract IEnumerator PhysObjectCoroutine(PhysGrabObject physGrabObject); [IteratorStateMachine(typeof(d__31))] internal virtual IEnumerator SetPropertiesCoroutine(PhysGrabObject physGrabObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__31(0) { <>4__this = this, physGrabObject = physGrabObject }; } protected virtual void DestroyPhysObject(PhysGrabObject physGrabObject) { ValuableObject val = default(ValuableObject); if (((Component)physGrabObject).TryGetComponent(ref val) && (Object)(object)physGrabObject.impactDetector != (Object)null) { physGrabObject.impactDetector.DestroyObject(true); } else { physGrabObject.DestroyPhysGrabObject(); } } protected override int GetSpawnCount() { return SpawnCount.Value; } } public abstract class MEventPhysTrapDrop : MEventPhysObjectDrop { [CompilerGenerated] private sealed class d__0 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PhysGrabObject physGrabObject; public MEventPhysTrapDrop <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; MEventPhysTrapDrop mEventPhysTrapDrop = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; Trap val = default(Trap); if (!((Component)physGrabObject).TryGetComponent(ref val)) { return false; } float value = mEventPhysTrapDrop.Duration.Value; val.triggerOnTimer = true; SyncedEventTimer val2 = default(SyncedEventTimer); if (((Component)val).TryGetComponent(ref val2)) { val2.timerMin = value; val2.timerMax = value; } val.TrapActivateSync(); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [IteratorStateMachine(typeof(d__0))] protected override IEnumerator PhysObjectCoroutine(PhysGrabObject physGrabObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(0) { <>4__this = this, physGrabObject = physGrabObject }; } } } namespace com.github.zehsteam.TwitchTrolling.Managers { internal static class ConfigManager { public static ConfigFile ConfigFile { get; private set; } public static ConfigEntry ExtendedLogging { get; private set; } public static ConfigEntry TwitchIntegration_Enabled { get; private set; } public static ConfigEntry TwitchSubEvent_Enabled { get; private set; } public static ConfigEntry TwitchSubEvent_Tier1EnemySpawnCountMultiplier { get; private set; } public static ConfigEntry TwitchSubEvent_Tier2EnemySpawnCountMultiplier { get; private set; } public static ConfigEntry TwitchSubEvent_Tier3EnemySpawnCountMultiplier { get; private set; } public static ConfigEntry TwitchCheerEvent_Enabled { get; private set; } public static ConfigEntry TwitchCheerEvent_EnableBitsForRandomEnemy { get; private set; } public static ConfigEntry TwitchCheerEvent_BitsForRandomEnemy { get; private set; } public static ConfigEntry TwitchRaidEvent_Enabled { get; private set; } public static ConfigEntry TwitchRaidEvent_ViewersPerRandomEnemy { get; private set; } public static ConfigEntry TwitchRaidEvent_MaxEnemySpawnCount { get; private set; } public static ConfigEntry Enemy_Enabled { get; private set; } public static ConfigEntry Enemy_SpawnDespawned { get; private set; } public static ConfigEntry Enemy_MinSpawnDistance { get; private set; } public static ConfigEntry Enemy_MaxSpawnDistance { get; private set; } public static ConfigEntry Event_Enabled { get; private set; } public static ConfigEntry Event_EnableBitsForRandomEvent { get; private set; } public static ConfigEntry Event_BitsForRandomEvent { get; private set; } public static ConfigEntry Message_Enabled { get; private set; } public static ConfigEntry Message_Duration { get; private set; } public static ConfigEntry Message_FontSize { get; private set; } public static ConfigEntry Message_BackgroundTransparency { get; private set; } public static ConfigEntry DeathMessage_Enabled { get; private set; } public static ConfigEntry DeathMessage_ShowPlatformIcon { get; private set; } public static ConfigEntry DeathMessage_Duration { get; private set; } public static ConfigEntry DeathMessage_FontSize { get; private set; } public static ConfigEntry DeathMessage_BackgroundTransparency { get; private set; } public static ConfigEntry EnemyNametag_Enabled { get; private set; } public static ConfigEntry EnemyNametag_ShowPlatformIcon { get; private set; } public static ConfigEntry EnemyNametag_SizeMultiplier { get; private set; } public static ConfigEntry EnemyNametag_BackgroundTransparency { get; private set; } public static void Initialize(ConfigFile configFile) { ConfigFile = configFile; BindConfigs(); MigrateOldConfigEntries(); ForceEnableEnemies(); } private static void BindConfigs() { ExtendedLogging = ConfigFile.Bind("- General -", "ExtendedLogging", false, "Enable extended logging."); TwitchIntegration_Enabled = ConfigFile.Bind("- Twitch Integration -", "Enabled", true, "If enabled, Twitch integration will be enabled to spawn enemies from Subs, Cheers, and Raids."); TwitchIntegration_Enabled.SettingChanged += delegate { PageManager.UpdatePage(); }; TwitchSubEvent_Enabled = ConfigFile.Bind("- Twitch Sub Event -", "Enabled", true, "If enabled, Twitch subs will be able to spawn enemies."); TwitchSubEvent_Tier1EnemySpawnCountMultiplier = ConfigFile.Bind("- Twitch Sub Event -", "Tier1EnemySpawnCountMultiplier", 1, "The amount to multiply the enemy spawn count for tier 1 subs.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 30)); TwitchSubEvent_Tier2EnemySpawnCountMultiplier = ConfigFile.Bind("- Twitch Sub Event -", "Tier2EnemySpawnCountMultiplier", 5, "The amount to multiply the enemy spawn count for tier 2 subs.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 30)); TwitchSubEvent_Tier3EnemySpawnCountMultiplier = ConfigFile.Bind("- Twitch Sub Event -", "Tier3EnemySpawnCountMultiplier", 10, "The amount to multiply the enemy spawn count for tier 3 subs.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 30)); TwitchSubEvent_Enabled.SettingChanged += delegate { PageManager.UpdatePage(); }; TwitchSubEvent_Tier1EnemySpawnCountMultiplier.SettingChanged += delegate { PageManager.UpdatePage(); }; TwitchSubEvent_Tier2EnemySpawnCountMultiplier.SettingChanged += delegate { PageManager.UpdatePage(); }; TwitchSubEvent_Tier3EnemySpawnCountMultiplier.SettingChanged += delegate { PageManager.UpdatePage(); }; TwitchCheerEvent_Enabled = ConfigFile.Bind("- Twitch Cheer Event -", "Enabled", true, "If enabled, Twitch cheers will be able to spawn enemies."); TwitchCheerEvent_EnableBitsForRandomEnemy = ConfigFile.Bind("- Twitch Cheer Event -", "EnableBitsForRandomEnemy", true, "If enabled, viewers can spawn random enemies with bits."); TwitchCheerEvent_BitsForRandomEnemy = ConfigFile.Bind("- Twitch Cheer Event -", "BitsForRandomEnemy", 350, "The min amount of bits to spawn a random enemy.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 1000)); TwitchCheerEvent_Enabled.SettingChanged += delegate { PageManager.UpdatePage(); }; TwitchCheerEvent_EnableBitsForRandomEnemy.SettingChanged += delegate { PageManager.UpdatePage(); }; TwitchCheerEvent_BitsForRandomEnemy.SettingChanged += delegate { PageManager.UpdatePage(); }; TwitchRaidEvent_Enabled = ConfigFile.Bind("- Twitch Raid Event -", "Enabled", true, "If enabled, Twitch raids will be able to spawn enemies."); TwitchRaidEvent_ViewersPerRandomEnemy = ConfigFile.Bind("- Twitch Raid Event -", "ViewersPerRandomEnemy", 5, "The amount of viewers for each random enemy spawn.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100)); TwitchRaidEvent_MaxEnemySpawnCount = ConfigFile.Bind("- Twitch Raid Event -", "MaxEnemySpawnCount", 20, "The max amount of enemies that can spawn from a raid.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100)); TwitchRaidEvent_Enabled.SettingChanged += delegate { PageManager.UpdatePage(); }; TwitchRaidEvent_ViewersPerRandomEnemy.SettingChanged += delegate { PageManager.UpdatePage(); }; TwitchRaidEvent_MaxEnemySpawnCount.SettingChanged += delegate { PageManager.UpdatePage(); }; Enemy_Enabled = ConfigFile.Bind("- Enemy -", "Enabled", true, "If enabled, Twitch events will be able to spawn enemies."); Enemy_SpawnDespawned = ConfigFile.Bind("- Enemy -", "SpawnDespawned", false, "If enabled, enemies will spawn despawned."); Enemy_MinSpawnDistance = ConfigFile.Bind("- Enemy -", "MinSpawnDistance", 25f, "The min distance an enemy can spawn from the local player. (meters)", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f)); Enemy_MaxSpawnDistance = ConfigFile.Bind("- Enemy -", "MaxSpawnDistance", 300f, "The max distance an enemy can spawn from the local player. (meters)", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 500f)); Enemy_Enabled.SettingChanged += delegate { PageManager.UpdatePage(); }; Event_Enabled = ConfigFile.Bind("- Event -", "Enabled", true, "If enabled, Twitch cheers will be able to trigger events."); Event_EnableBitsForRandomEvent = ConfigFile.Bind("- Event -", "EnableBitsForRandomEvent", true, "If enabled, viewers can trigger random events with bits."); Event_BitsForRandomEvent = ConfigFile.Bind("- Event -", "BitsForRandomEvent", 150, "The amount of bits to trigger a random event.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 1000)); Event_Enabled.SettingChanged += delegate { PageManager.UpdatePage(); }; Event_EnableBitsForRandomEvent.SettingChanged += delegate { PageManager.UpdatePage(); }; Event_BitsForRandomEvent.SettingChanged += delegate { PageManager.UpdatePage(); }; Message_Enabled = ConfigFile.Bind("- Message -", "Enabled", true, "If enabled, will show messages in the bottom right."); Message_Duration = ConfigFile.Bind("- Message -", "Duration", 10f, "The duration of a message. (seconds)", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 60f)); Message_FontSize = ConfigFile.Bind("- Message -", "FontSize", 12, "The font size of the messages.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 50)); Message_BackgroundTransparency = ConfigFile.Bind("- Message -", "BackgroundTransparency", 192, "The transparency of the message background.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 255)); Message_FontSize.SettingChanged += delegate { MessageItem.OnConfigSettingsChanged(); }; Message_BackgroundTransparency.SettingChanged += delegate { MessageItem.OnConfigSettingsChanged(); }; DeathMessage_Enabled = ConfigFile.Bind("- Death Message -", "Enabled", true, "If enabled, will show a message when you die to an enemy spawned from a viewer."); DeathMessage_ShowPlatformIcon = ConfigFile.Bind("- Death Message -", "ShowPlatformIcon", true, "If enabled, will show which platform the enemy was spawned from."); DeathMessage_Duration = ConfigFile.Bind("- Death Message -", "Duration", 8f, "The duration of the death message. (seconds)", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 60f)); DeathMessage_FontSize = ConfigFile.Bind("- Death Message -", "FontSize", 16, "The font size of the death message.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 50)); DeathMessage_BackgroundTransparency = ConfigFile.Bind("- Death Message -", "BackgroundTransparency", 192, "The transparency of the death message background.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 255)); EnemyNametag_Enabled = ConfigFile.Bind("- Enemy Nametag -", "Enabled", true, "If enabled, enemies will spawn with a nametag of the viewer that spawned that enemy."); EnemyNametag_ShowPlatformIcon = ConfigFile.Bind("- Enemy Nametag -", "ShowPlatformIcon", true, "If enabled, nametags will show which platform the enemy was spawned from."); EnemyNametag_SizeMultiplier = ConfigFile.Bind("- Enemy Nametag -", "SizeMultiplier", 0.75f, "The size multiplier for enemy nametags.", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 5f)); EnemyNametag_BackgroundTransparency = ConfigFile.Bind("- Enemy Nametag -", "BackgroundTransparency", 192, "The transparency of the nametag background.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 255)); EnemyNametag_ShowPlatformIcon.SettingChanged += delegate { EnemyNametag.OnConfigSettingsChanged(); }; EnemyNametag_SizeMultiplier.SettingChanged += delegate { EnemyNametag.OnConfigSettingsChanged(); }; EnemyNametag_BackgroundTransparency.SettingChanged += delegate { EnemyNametag.OnConfigSettingsChanged(); }; } private static void MigrateOldConfigEntries() { Dictionary dictionary = new Dictionary(ConfigFile.GetOrphanedConfigEntries()); foreach (KeyValuePair item in dictionary) { MigrateOldConfigEntry(item.Key, item.Value); } ConfigFile.Save(); } private static void MigrateOldConfigEntry(ConfigDefinition configDefinition, string value) { string section = configDefinition.Section; string key = configDefinition.Key; StringComparison comparisonType = StringComparison.OrdinalIgnoreCase; if (section.Equals("- Twitch Cheer Event -", comparisonType)) { if (key.Equals("MinAmountForRandomEnemy", comparisonType)) { ConfigFile.MigrateConfigEntry(configDefinition, value, TwitchCheerEvent_BitsForRandomEnemy); } } else if (section.Equals("- Event -", comparisonType) && key.Equals("AmountForRandomEvent", comparisonType)) { ConfigFile.MigrateConfigEntry(configDefinition, value, Event_BitsForRandomEvent); } } private static void ForceEnableEnemies() { string key = "ForceEnabledEnemies"; if (!Plugin.LocalSave.Load(key, defaultValue: false)) { Plugin.LocalSave.Save(key, value: true); Enemy_Enabled.Value = true; } } } internal static class EnemyConfigManager { public static ConfigFile ConfigFile => ConfigManager.ConfigFile; public static List ConfigEntries { get; private set; } = new List(); public static List EnabledConfigEntries => ConfigEntries.Where((EnemyConfigEntry x) => x.Enabled.Value).ToList(); public static void Initialize() { EnemyConfigEntryDefaultValues[] list = Assets.EnemyConfigEntryDefaultValuesList.List; foreach (EnemyConfigEntryDefaultValues defaultValues in list) { RegisterConfigEntry(defaultValues); } foreach (EnemySetup allEnemy in Enemies.AllEnemies) { if (allEnemy.TryGetEnemyName(out var enemyName)) { RegisterConfigEntry(enemyName); } } } public static void RegisterConfigEntry(string enemyName) { if (!HasConfigEntry(enemyName)) { EnemyConfigEntry item = new EnemyConfigEntry(enemyName); ConfigEntries.Add(item); } } public static void RegisterConfigEntry(EnemyConfigEntryDefaultValues defaultValues) { if (!HasConfigEntry(defaultValues.EnemyName)) { EnemyConfigEntry item = new EnemyConfigEntry(defaultValues); ConfigEntries.Add(item); } } public static bool HasEnemies() { return EnabledConfigEntries.Count > 0; } public static bool HasConfigEntry(string enemyName) { return ConfigEntries.Any((EnemyConfigEntry x) => x.EnemyNameEquals(enemyName)); } public static EnemyConfigEntry GetConfigEntry(string enemyName) { return ConfigEntries.FirstOrDefault((EnemyConfigEntry x) => x.EnemyNameEquals(enemyName)); } public static bool TryGetConfigEntry(string enemyName, out EnemyConfigEntry configEntry) { configEntry = GetConfigEntry(enemyName); return configEntry != null; } public static List GetConfigEntriesThatMatchBitsAmount(int bitsAmount, bool includeDisable = false) { List list = new List(); foreach (EnemyConfigEntry configEntry in ConfigEntries) { if ((includeDisable || configEntry.Enabled.Value) && configEntry.BitsToSpawn.Value == bitsAmount) { list.Add(configEntry); } } return list; } public static bool TryGetConfigEntriesThatMatchBitsAmount(int bitsAmount, out List list, bool includeDisable = false) { list = GetConfigEntriesThatMatchBitsAmount(bitsAmount, includeDisable); return list.Any(); } public static List GetConfigEntriesThatMatchSubsAmount(int subsAmount, bool includeDisable = false) { List list = new List(); foreach (EnemyConfigEntry configEntry in ConfigEntries) { if ((includeDisable || configEntry.Enabled.Value) && configEntry.SubsToSpawn.Value == subsAmount) { list.Add(configEntry); } } return list; } public static bool TryGetConfigEntriesThatMatchSubsAmount(int subsAmount, out List list, bool includeDisable = false) { list = GetConfigEntriesThatMatchSubsAmount(subsAmount, includeDisable); return list.Any(); } } internal static class EnemyManager { private static AudioPlayerFactory _audioPlayerFactory; public static Dictionary ViewerEnemies { get; private set; } public static bool SpawnDespawned => ConfigManager.Enemy_SpawnDespawned.Value; public static float MinSpawnDistance => ConfigManager.Enemy_MinSpawnDistance.Value; public static float MaxSpawnDistance => ConfigManager.Enemy_MaxSpawnDistance.Value; static EnemyManager() { ViewerEnemies = new Dictionary(); _audioPlayerFactory = new AudioPlayerFactory { Type = AudioPlayerType.EnemySpawn, MaxDistance = 30f }; } public static void ResetViewerEnemies() { ViewerEnemies.Clear(); } public static void SpawnEnemy(ViewerSpawnData viewerSpawnData) { if (viewerSpawnData == null) { Logger.LogError("EnemyManager: Failed to spawn enemies. ViewerSpawnData is null.", extended: false, showMessage: true); return; } if (!CanSpawnEnemies()) { Logger.LogError("EnemyManager: Failed to spawn enemies. You are not allowed to spawn enemies at this time.", extended: false, showMessage: true); return; } List entries = new List(); for (int i = 0; i < viewerSpawnData.SpawnCount; i++) { if (EnemyConfigManager.TryGetConfigEntry(viewerSpawnData.TargetEnemyName, out var configEntry)) { entries.Add(configEntry); } else { entries.Add(EnemyConfigManager.ConfigEntries.GetRandom()); } } if (entries.Count < 1) { Logger.LogError("EnemyManager: Failed to spawn enemies. No enemies where found to spawn.", extended: false, showMessage: true); return; } if (entries.All((EnemyConfigEntry x) => x == entries[0])) { viewerSpawnData.SetTargetEnemyName(entries[0].EnemyName); } int num = entries.Sum((EnemyConfigEntry x) => x.SpawnCount.Value); viewerSpawnData.SetTotalSpawnCount(num); if (num < 1) { Logger.LogError("EnemyManager: Failed to spawn enemies. Total spawn count is less than 1.", extended: false, showMessage: true); return; } foreach (EnemyConfigEntry item in entries) { SpawnEnemy(item, viewerSpawnData.Viewer); } MessageManager.Instance?.ShowSpawnEnemyMessage(viewerSpawnData); Logger.LogInfo($"\n\n{viewerSpawnData.Viewer.DisplayName} spawned {num}x enemies {viewerSpawnData.SpawnReason}\n", extended: true); } private static void SpawnEnemy(EnemyConfigEntry configEntry, ViewerData viewerData) { if (configEntry == null) { Logger.LogError("EnemyManager: Failed to spawn enemies. EnemyConfigEntry is null.", extended: false, showMessage: true); return; } if (viewerData == null) { Logger.LogError("EnemyManager: Failed to spawn enemies. ViewerData is null.", extended: false, showMessage: true); return; } string enemyName = configEntry.EnemyName; int value = configEntry.SpawnCount.Value; if (value < 1) { Logger.LogError("EnemyManager: Failed to spawn enemy \"" + enemyName + "\". Spawn count is less than 1.", extended: false, showMessage: true); return; } if (!TryGetEnemyByName(enemyName, out var enemySetup)) { Logger.LogError("EnemyManager: Failed to spawn enemy \"" + enemyName + "\". EnemySetup is null.", extended: false, showMessage: true); return; } for (int i = 0; i < value; i++) { SpawnEnemy(enemySetup, viewerData); } } private static void SpawnEnemy(EnemySetup enemySetup, ViewerData viewerData) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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) if ((Object)(object)enemySetup == (Object)null) { Logger.LogError("EnemyManager: Failed to spawn enemies. EnemySetup is null.", extended: false, showMessage: true); return; } if (viewerData == null) { Logger.LogError("EnemyManager: Failed to spawn enemies. ViewerData is null.", extended: false, showMessage: true); return; } EnemyParent val = default(EnemyParent); if (!EnemySetupExtensions.TryGetEnemyParent(enemySetup, ref val)) { Logger.LogError("EnemyManager: Failed to spawn enemy. EnemyParent is null.", extended: false, showMessage: true); return; } Vector3 randomSpawnPosition = GetRandomSpawnPosition(); List list = Enemies.SpawnEnemy(enemySetup, randomSpawnPosition, Quaternion.identity, SpawnDespawned); PlayerAvatar localPlayer = PlayerHelper.GetLocalPlayer(); EnemyNametag enemyNametag = default(EnemyNametag); foreach (EnemyParent item in list) { ViewerEnemies.Add(item, viewerData); ParticleScriptExplosion[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); foreach (ParticleScriptExplosion component in componentsInChildren) { ((Component)(object)component).SetViewerMetadata(viewerData); } GameObject val2 = Object.Instantiate(Assets.EnemyNametagWorldCanvasPrefab); if (val2.TryGetComponent(ref enemyNametag)) { enemyNametag.SetData(item, viewerData); } AudioClip spawnSFX = Assets.EnemySpawnSFXList.GetSpawnSFX(item.enemyName); _audioPlayerFactory?.Play(spawnSFX, ((Component)item).transform.position); if ((Object)(object)localPlayer != (Object)null) { float num = Vector3.Distance(((Component)item).transform.position, ((Component)localPlayer).transform.position); Logger.LogInfo($"Spawned \"{item.enemyName}\" {num} meters away from you.", extended: true); } } } private static Vector3 GetRandomSpawnPosition() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0040: 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_0085: 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_007c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)LevelGenerator.Instance == (Object)null) { Logger.LogError("EnemyManager: Failed to get valid spawn position. LevelGenerator instance is null.", extended: false, showMessage: true); return Vector3.zero; } Vector3 val = Vector3.zero; float minSpawnDistance = MinSpawnDistance; float maxSpawnDistance = MaxSpawnDistance; if (PlayerHelper.TryGetLocalPlayer(out var playerAvatar)) { val = ((Component)playerAvatar).transform.position; } LevelPoint val2 = SemiFunc.LevelPointGet(val, minSpawnDistance, maxSpawnDistance); if ((Object)(object)val2 == (Object)null) { val2 = SemiFunc.LevelPointGet(val, Mathf.Min(minSpawnDistance, 25f), float.MaxValue); if ((Object)(object)val2 == (Object)null) { return val; } } return ((Component)val2).transform.position; } public static bool CanSpawnEnemies() { if (!SemiFunc.IsMasterClientOrSingleplayer()) { return false; } if (!LevelHelper.CurrentLevelHasEnemies()) { return false; } if (!PlayerHelper.IsLocalPlayerAlive()) { return false; } return true; } public static ViewerData GetViewerData(EnemyParent enemyParent) { if ((Object)(object)enemyParent == (Object)null) { return null; } if (ViewerEnemies.TryGetValue(enemyParent, out var value)) { return value; } return null; } public static bool TryGetViewerData(EnemyParent enemyParent, out ViewerData viewerData) { viewerData = GetViewerData(enemyParent); return viewerData != null; } public static EnemySetup GetEnemyByName(string name) { return ((IEnumerable)Enemies.AllEnemies).FirstOrDefault((Func)((EnemySetup x) => x.GetEnemyName() == name)); } public static bool TryGetEnemyByName(string name, out EnemySetup enemySetup) { enemySetup = GetEnemyByName(name); return (Object)(object)enemySetup != (Object)null; } } internal static class PageManager { internal enum TwitchChannelStatus { None, Accepted, NotLive, NotAffiliateOrPartner, Banned, FailedToCheck } [CompilerGenerated] private sealed class d__28 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private UnityWebRequest 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__28(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Invalid comparison between Unknown and I4 //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Invalid comparison between Unknown and I4 bool result; try { switch (<>1__state) { default: result = false; break; case 0: { <>1__state = -1; string pageId = GetPageId(); string pageAccessToken = GetPageAccessToken(); if (string.IsNullOrEmpty(pageId) || string.IsNullOrEmpty(pageAccessToken)) { HasPage = false; PageManager.OnPageStatusChanged?.Invoke(); result = false; break; } string text = "https://twitchtrolling.up.railway.app/api/pages/" + pageId; 5__2 = UnityWebRequest.Get(text); <>1__state = -3; <>2__current = 5__2.SendWebRequest(); <>1__state = 1; result = true; break; } case 1: <>1__state = -3; if ((int)5__2.result == 3 && 5__2.responseCode == 404) { Logger.LogWarning("Page not found (404). Clearing saved page ID and access token."); SavePageId(string.Empty); SavePageAccessToken(string.Empty); HasPage = false; PageManager.OnPageStatusChanged?.Invoke(); result = false; } else if ((int)5__2.result != 1) { Logger.LogWarning("Page status check failed: " + 5__2.error); HasPage = false; PageManager.OnPageStatusChanged?.Invoke(); result = false; } else { HasPage = true; PageManager.OnPageStatusChanged?.Invoke(); result = false; } <>m__Finally1(); break; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (5__2 != null) { ((IDisposable)5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__29 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private UnityWebRequest 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__29(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Invalid comparison between Unknown and I4 bool result; try { switch (<>1__state) { default: result = false; break; case 0: { <>1__state = -1; if (!IsCreatePageEnabled(out var reason)) { Logger.LogError("You are unable to create a page: " + reason); result = false; break; } string text4 = "https://twitchtrolling.up.railway.app/api/pages"; string s = JsonConvert.SerializeObject((object)GetDataForPage()); 5__2 = new UnityWebRequest(text4, "POST"); <>1__state = -3; byte[] bytes = Encoding.UTF8.GetBytes(s); 5__2.uploadHandler = (UploadHandler)new UploadHandlerRaw(bytes); 5__2.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); 5__2.SetRequestHeader("Content-Type", "application/json"); 5__2.SetRequestHeader("Authorization", "Bearer d74c6ba6-4584-4969-8af9-066549673563"); <>2__current = 5__2.SendWebRequest(); <>1__state = 1; result = true; break; } case 1: { <>1__state = -3; if ((int)5__2.result != 1) { Logger.LogError("Failed to create page: " + 5__2.error, extended: false, showMessage: true); PageManager.OnPageStatusChanged?.Invoke(); result = false; } else { string text = 5__2.downloadHandler.text; JObject val; try { val = JObject.Parse(text); } catch (Exception ex) { Logger.LogError("Failed to parse create page response: " + ex.Message, extended: false, showMessage: true); PageManager.OnPageStatusChanged?.Invoke(); result = false; goto IL_023d; } string text2 = ((object)val["id"])?.ToString(); string text3 = ((object)val["accessToken"])?.ToString(); if (string.IsNullOrEmpty(text2) || string.IsNullOrEmpty(text3)) { Logger.LogError("Create page response missing required fields.", extended: false, showMessage: true); PageManager.OnPageStatusChanged?.Invoke(); result = false; } else { SavePageId(text2); SavePageAccessToken(text3); HasPage = true; _updatePageDataFirstTime = true; PageManager.OnPageCreated?.Invoke(PageURL); MessageManager.Instance?.ShowMessage("Please share the page url with your viewers"); MessageManager.Instance?.ShowMessage("It is recommended that you pin it in your chat"); result = false; } } goto IL_023d; } IL_023d: <>m__Finally1(); break; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (5__2 != null) { ((IDisposable)5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__30 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public TimeSpan delay; private UnityWebRequest 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__30(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 2) { try { } finally { <>m__Finally1(); } } 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Invalid comparison between Unknown and I4 //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown bool result; try { switch (<>1__state) { default: result = false; break; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds((float)delay.TotalSeconds); <>1__state = 1; result = true; break; case 1: { <>1__state = -1; string pageId = GetPageId(); string pageAccessToken = GetPageAccessToken(); if (string.IsNullOrEmpty(pageId) || string.IsNullOrEmpty(pageAccessToken)) { Logger.LogWarning("UpdatePage: Missing Page ID or Access Token."); result = false; break; } string text = "https://twitchtrolling.up.railway.app/api/pages/" + pageId; string s = JsonConvert.SerializeObject((object)GetDataForPage()); 5__2 = new UnityWebRequest(text, "PUT"); <>1__state = -3; byte[] bytes = Encoding.UTF8.GetBytes(s); 5__2.uploadHandler = (UploadHandler)new UploadHandlerRaw(bytes); 5__2.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); 5__2.SetRequestHeader("Content-Type", "application/json"); 5__2.SetRequestHeader("Authorization", "Bearer " + pageAccessToken); <>2__current = 5__2.SendWebRequest(); <>1__state = 2; result = true; break; } case 2: <>1__state = -3; if ((int)5__2.result != 1) { Logger.LogError("Failed to update page: " + 5__2.error, extended: false, showMessage: true); result = false; } else { Logger.LogInfo("Page updated successfully.", extended: true); result = false; } <>m__Finally1(); break; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (5__2 != null) { ((IDisposable)5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__43 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private UnityWebRequest 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__43(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Invalid comparison between Unknown and I4 //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Invalid comparison between Unknown and I4 bool result; try { JObject val2; switch (<>1__state) { default: result = false; break; case 0: { <>1__state = -1; _twitchChannelStatus = TwitchChannelStatus.None; if ((int)API.ConnectionState != 2) { PageManager.OnPageStatusChanged?.Invoke(); result = false; break; } string channel = API.Channel; if (channel.Equals("CritHaxXoG", StringComparison.OrdinalIgnoreCase)) { _twitchChannelStatus = TwitchChannelStatus.Accepted; PageManager.OnPageStatusChanged?.Invoke(); result = false; break; } string text2 = "https://api.ivr.fi/v2/twitch/user?login=" + channel; 5__2 = UnityWebRequest.Get(text2); <>1__state = -3; 5__2.SetRequestHeader("User-Agent", "TwitchTrolling/1.8.0"); <>2__current = 5__2.SendWebRequest(); <>1__state = 1; result = true; break; } case 1: { <>1__state = -3; if ((int)5__2.result != 1) { Logger.LogError("VerifyTwitchChannel: Failed to verify Twitch channel."); _twitchChannelStatus = TwitchChannelStatus.FailedToCheck; PageManager.OnPageStatusChanged?.Invoke(); result = false; } else { string text = 5__2.downloadHandler.text; try { JArray val = JArray.Parse(text); if (((JContainer)val).Count != 0) { val2 = (JObject)val[0]; goto IL_019c; } Logger.LogWarning("VerifyTwitchChannel: No user found with the specified login."); _twitchChannelStatus = TwitchChannelStatus.FailedToCheck; PageManager.OnPageStatusChanged?.Invoke(); result = false; } catch (Exception ex) { Logger.LogError("VerifyTwitchChannel: Failed to parse Twitch user response: " + ex.Message); _twitchChannelStatus = TwitchChannelStatus.FailedToCheck; PageManager.OnPageStatusChanged?.Invoke(); result = false; } } goto IL_0283; } IL_019c: if (((JToken)val2).Value((object)"banned")) { _twitchChannelStatus = TwitchChannelStatus.Banned; PageManager.OnPageStatusChanged?.Invoke(); result = false; } else { JObject val3 = (JObject)(((object)((JToken)val2).Value((object)"roles")) ?? ((object)new JObject())); bool valueOrDefault = ((JToken)val3).Value((object)"isAffiliate").GetValueOrDefault(); bool valueOrDefault2 = ((JToken)val3).Value((object)"isPartner").GetValueOrDefault(); if (!valueOrDefault && !valueOrDefault2) { _twitchChannelStatus = TwitchChannelStatus.NotAffiliateOrPartner; PageManager.OnPageStatusChanged?.Invoke(); result = false; } else if (val2["stream"] == null || (int)val2["stream"].Type == 10) { _twitchChannelStatus = TwitchChannelStatus.NotLive; PageManager.OnPageStatusChanged?.Invoke(); result = false; } else { _twitchChannelStatus = TwitchChannelStatus.Accepted; PageManager.OnPageStatusChanged?.Invoke(); result = false; } } goto IL_0283; IL_0283: <>m__Finally1(); break; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (5__2 != null) { ((IDisposable)5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const bool DEBUG = false; private const string API_ORIGIN = "https://twitchtrolling.up.railway.app"; private const string CREATE_PAGE_TOKEN = "d74c6ba6-4584-4969-8af9-066549673563"; private static bool _updatePageDataFirstTime; private static float _lastUpdatePageTime = float.NegativeInfinity; private const float _updatePageCooldown = 0.1f; private static string _previousChannel; private static TwitchChannelStatus _twitchChannelStatus; public static bool HasPage { get; private set; } public static string PageId => GetPageId(); public static string PageURL { get { if (!HasPage) { return string.Empty; } return "https://twitchtrolling.com/page?id=" + PageId; } } public static event Action OnPageStatusChanged; public static event Action OnPageCreated; public static void Initialize() { API.OnConnect += HandleTwitchOnConnect; Application.quitting += delegate { API.OnConnect -= HandleTwitchOnConnect; }; _previousChannel = API.Channel; CheckPageStatus(); VerifyTwitchChannel(); } public static void CheckPageStatus() { PluginManager instance = PluginManager.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(CheckPageStatusCoroutine()); } } public static void CreatePage() { PluginManager instance = PluginManager.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(CreatePageCoroutine()); } } public static void UpdatePage() { if (HasPage) { float num = 0.1f; float realtimeSinceStartup = Time.realtimeSinceStartup; if (!(realtimeSinceStartup - _lastUpdatePageTime < num)) { _lastUpdatePageTime = realtimeSinceStartup; ((MonoBehaviour)PluginManager.Instance).StartCoroutine(UpdatePageCoroutine(TimeSpan.FromSeconds(num))); } } } public static void UpdatePageFirstTime() { if (!_updatePageDataFirstTime) { _updatePageDataFirstTime = true; UpdatePage(); } } [IteratorStateMachine(typeof(d__28))] private static IEnumerator CheckPageStatusCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__28(0); } [IteratorStateMachine(typeof(d__29))] private static IEnumerator CreatePageCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__29(0); } [IteratorStateMachine(typeof(d__30))] private static IEnumerator UpdatePageCoroutine(TimeSpan delay) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__30(0) { delay = delay }; } private static JObject GetDataForPage() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0080: Expected O, but got Unknown bool isCheerEventEnabled = TwitchIntegrationManager.IsCheerEventEnabled; bool isSubEventEnabled = TwitchIntegrationManager.IsSubEventEnabled; bool isRaidEventEnabled = TwitchIntegrationManager.IsRaidEventEnabled; JObject val = new JObject { ["channel"] = JToken.op_Implicit(API.Channel), ["cheerEnabled"] = JToken.op_Implicit(isCheerEventEnabled), ["subEnabled"] = JToken.op_Implicit(isSubEventEnabled), ["raidEnabled"] = JToken.op_Implicit(isRaidEventEnabled), ["enemies"] = (JToken)(object)GetEnemyDataForPage(), ["events"] = (JToken)(object)GetEventDataForPage() }; if (isSubEventEnabled) { val.Add("subEnemySpawnCountMultipliers", (JToken)(object)GetSubEnemySpawnCountMultipliersForPage()); } if (isRaidEventEnabled) { val.Add("raid", (JToken)(object)GetRaidDataForPage()); } return val; } private static JArray GetEnemyDataForPage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown JArray val = new JArray(); if (!TwitchIntegrationManager.IsEnabled || !TwitchIntegrationManager.IsCheerEventEnabled) { return val; } if (!ConfigManager.Enemy_Enabled.Value) { return val; } if (ConfigManager.TwitchCheerEvent_EnableBitsForRandomEnemy.Value && EnemyConfigManager.EnabledConfigEntries.Count > 1) { JObject val2 = new JObject { ["name"] = JToken.op_Implicit("Random Enemy"), ["price"] = JToken.op_Implicit(ConfigManager.TwitchCheerEvent_BitsForRandomEnemy.Value) }; val.Add((JToken)(object)val2); } foreach (EnemyConfigEntry configEntry in EnemyConfigManager.ConfigEntries) { if (configEntry.Enabled.Value) { val.Add((JToken)(object)configEntry.GetCardJSON()); } } return val; } private static JArray GetEventDataForPage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown JArray val = new JArray(); if (!TwitchIntegrationManager.IsEnabled || !TwitchIntegrationManager.IsCheerEventEnabled) { return val; } if (!MEventManager.Enabled) { return val; } if (ConfigManager.Event_EnableBitsForRandomEvent.Value && MEventManager.EnabledEvents.Count > 1) { JObject val2 = new JObject { ["name"] = JToken.op_Implicit("Random Event"), ["price"] = JToken.op_Implicit(ConfigManager.Event_BitsForRandomEvent.Value) }; val.Add((JToken)(object)val2); } foreach (MEvent @event in MEventManager.Events) { if (@event.Enabled.Value) { val.Add((JToken)(object)@event.GetCardJSON()); } } return val; } private static JObject GetRaidDataForPage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown return new JObject { ["viewersPerRandomEnemy"] = JToken.op_Implicit(ConfigManager.TwitchRaidEvent_ViewersPerRandomEnemy.Value), ["maxEnemySpawnCount"] = JToken.op_Implicit(ConfigManager.TwitchRaidEvent_MaxEnemySpawnCount.Value) }; } private static JObject GetSubEnemySpawnCountMultipliersForPage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown return new JObject { ["tier1"] = JToken.op_Implicit(ConfigManager.TwitchSubEvent_Tier1EnemySpawnCountMultiplier.Value), ["tier2"] = JToken.op_Implicit(ConfigManager.TwitchSubEvent_Tier2EnemySpawnCountMultiplier.Value), ["tier3"] = JToken.op_Implicit(ConfigManager.TwitchSubEvent_Tier3EnemySpawnCountMultiplier.Value) }; } private static string GetPageId() { return Plugin.GlobalSave.Load("PageId", string.Empty); } private static string GetPageAccessToken() { return Plugin.GlobalSave.Load("PageAccessToken", string.Empty); } private static void SavePageId(string pageId) { Plugin.GlobalSave.Save("PageId", pageId); } private static void SavePageAccessToken(string accessToken) { Plugin.GlobalSave.Save("PageAccessToken", accessToken); } private static void HandleTwitchOnConnect() { string channel = API.Channel; if (!(_previousChannel == channel)) { _previousChannel = channel; VerifyTwitchChannel(); UpdatePage(); } } public static bool IsCreatePageEnabled(out string reason) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 reason = string.Empty; if ((int)API.ConnectionState != 2) { reason = "You are not connected to Twitch!"; return false; } if (_twitchChannelStatus == TwitchChannelStatus.None) { reason = "Your Twitch channel does not meet the requirements!"; return false; } if (_twitchChannelStatus == TwitchChannelStatus.NotLive) { reason = "You are not live!"; return false; } if (_twitchChannelStatus == TwitchChannelStatus.NotAffiliateOrPartner) { reason = "Your Twitch channel is not affiliate or partner!"; return false; } if (_twitchChannelStatus == TwitchChannelStatus.Banned) { reason = "Your Twitch channel is banned!"; return false; } return true; } public static void VerifyTwitchChannel() { PluginManager instance = PluginManager.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(VerifyTwitchChannelCoroutine()); } } [IteratorStateMachine(typeof(d__43))] private static IEnumerator VerifyTwitchChannelCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__43(0); } } } namespace com.github.zehsteam.TwitchTrolling.Helpers { internal static class AudioClipUtils { public static AudioClip ScaleVolume(AudioClip clip, float volumeMultiplier) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 if ((Object)(object)clip == (Object)null) { Debug.LogError((object)"AudioClipUtils: AudioClip is null."); return null; } if ((int)clip.loadState != 2) { Debug.LogWarning((object)"AudioClipUtils: AudioClip is not ready to play. This may cause issues."); } float[] array = new float[clip.samples * clip.channels]; clip.GetData(array, 0); for (int i = 0; i < array.Length; i++) { array[i] *= volumeMultiplier; array[i] = Mathf.Clamp(array[i], -1f, 1f); } AudioClip val = AudioClip.Create(((Object)clip).name + "_Scaled", clip.samples, clip.channels, clip.frequency, false); val.SetData(array, 0); return val; } } internal static class ColorHelper { private static readonly float _minContrastRatio = 2f; public static string GetReadableColor(string hexColor, string backgroundHexColor = "#000000") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Color val = HexToColor(hexColor); Color bgColor = HexToColor(backgroundHexColor); if (!HasGoodContrast(val, bgColor)) { val = AdjustColorForContrast(val, bgColor); } return ColorToHex(val); } public static Color HexToColor(string hex) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (!ColorUtility.TryParseHtmlString(hex, ref result)) { return Color.white; } return result; } public static string ColorToHex(Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGB(color); } private static bool HasGoodContrast(Color textColor, Color bgColor) { //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) float contrastRatio = GetContrastRatio(textColor, bgColor); return contrastRatio >= _minContrastRatio; } private static float GetContrastRatio(Color color1, Color color2) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) float luminance = GetLuminance(color1); float luminance2 = GetLuminance(color2); return (Mathf.Max(luminance, luminance2) + 0.05f) / (Mathf.Min(luminance, luminance2) + 0.05f); } private static float GetLuminance(Color color) { //IL_0005: 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_0032: Unknown result type (might be due to invalid IL or missing references) return 0.2126f * Mathf.Pow(color.r, 2.2f) + 0.7152f * Mathf.Pow(color.g, 2.2f) + 0.0722f * Mathf.Pow(color.b, 2.2f); } private static Color AdjustColorForContrast(Color textColor, Color bgColor) { //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) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0057: Unknown result type (might be due to invalid IL or missing references) float contrastRatio = GetContrastRatio(textColor, bgColor); if (contrastRatio >= _minContrastRatio) { return textColor; } RGBToHSL(textColor, out var h, out var s, out var l); float luminance = GetLuminance(bgColor); return HSLToRGB(l: (!(l < 0.5f)) ? Mathf.Max(l - 0.5f, 0f) : Mathf.Min(l + 0.5f, 1f), h: h, s: s); } private static void RGBToHSL(Color color, out float h, out float s, out float l) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) float r = color.r; float g = color.g; float b = color.b; float num = Mathf.Max(new float[3] { r, g, b }); float num2 = Mathf.Min(new float[3] { r, g, b }); float num3 = num - num2; l = (num + num2) / 2f; if (num3 == 0f) { h = 0f; s = 0f; return; } s = ((l > 0.5f) ? (num3 / (2f - num - num2)) : (num3 / (num + num2))); if (num == r) { h = (g - b) / num3 + (float)((g < b) ? 6 : 0); } else if (num == g) { h = (b - r) / num3 + 2f; } else { h = (r - g) / num3 + 4f; } h /= 6f; } private static Color HSLToRGB(float h, float s, float l) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) float num3; float num2; float num; if (s == 0f) { num3 = (num2 = (num = l)); } else { float num4 = ((l < 0.5f) ? (l * (1f + s)) : (l + s - l * s)); float p = 2f * l - num4; num3 = HueToRGB(p, num4, h + 1f / 3f); num2 = HueToRGB(p, num4, h); num = HueToRGB(p, num4, h - 1f / 3f); } return new Color(num3, num2, num); } private static float HueToRGB(float p, float q, float t) { if (t < 0f) { t += 1f; } if (t > 1f) { t -= 1f; } if (t < 1f / 6f) { return p + (q - p) * 6f * t; } if (t < 0.5f) { return q; } if (t < 2f / 3f) { return p + (q - p) * (2f / 3f - t) * 6f; } return p; } } internal class GridUtils { public static List GenerateGridAroundPosition(Vector3 center, float radius, float spacing, float minDistanceFromCenter = 0f) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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) List list = new List(); int num = Mathf.FloorToInt(radius / spacing); float y = center.y; Vector3 val = default(Vector3); Vector3 item = default(Vector3); for (int i = -num; i <= num; i++) { for (int j = -num; j <= num; j++) { ((Vector3)(ref val))..ctor((float)i * spacing, 0f, (float)j * spacing); ((Vector3)(ref item))..ctor(center.x + val.x, y, center.z + val.z); Vector2 val2 = new Vector2(val.x, val.z); float magnitude = ((Vector2)(ref val2)).magnitude; if (!(magnitude < minDistanceFromCenter) && !(magnitude > radius)) { list.Add(item); } } } return list.OrderBy((Vector3 p) => Vector2.Distance(new Vector2(p.x, p.z), new Vector2(center.x, center.z))).ToList(); } } internal static class ItemHelper { public static Item GetItemByName(string name) { return ((IEnumerable)Items.AllItems).FirstOrDefault((Func)((Item x) => x.itemName == name)); } public static bool TryGetItemByName(string name, out Item item) { item = GetItemByName(name); return (Object)(object)item != (Object)null; } } internal class JsonConvertHelper { public static string SerializeQueue(Queue queue) { if (queue == null) { queue = new Queue(); } return JsonConvert.SerializeObject((object)queue, (JsonConverter[])(object)new JsonConverter[1] { new QueueJsonConverter() }); } public static Queue DeserializeQueue(string value) { if (string.IsNullOrEmpty(value)) { return new Queue(); } return JsonConvert.DeserializeObject>(value, (JsonConverter[])(object)new JsonConverter[1] { new QueueJsonConverter() }); } } internal static class LevelHelper { public static Level GetCurrentLevel() { if ((Object)(object)RunManager.instance == (Object)null) { return null; } return RunManager.instance.levelCurrent; } public static bool CurrentLevelHasEnemies() { Level currentLevel = GetCurrentLevel(); if ((Object)(object)currentLevel == (Object)null) { return false; } return currentLevel.HasEnemies; } } internal static class NavMeshHelper { private static int _attempts = 50; private static float _raycastHeight = 1f; private static float _raycastLength = 50f; private static float _navMeshSampleDistance = 2f; public static bool TryGetPositionInRadius(Vector3 origin, float minDistance, float maxDistance, out Vector3 position) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0043: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) Vector3 val2 = default(Vector3); RaycastHit val3 = default(RaycastHit); NavMeshHit val4 = default(NavMeshHit); for (int i = 0; i < _attempts; i++) { Vector2 insideUnitCircle = Random.insideUnitCircle; Vector2 val = ((Vector2)(ref insideUnitCircle)).normalized * Random.Range(minDistance, maxDistance); ((Vector3)(ref val2))..ctor(origin.x + val.x, origin.y + _raycastHeight, origin.z + val.y); if (Physics.Raycast(val2, Vector3.down, ref val3, _raycastLength) && NavMesh.SamplePosition(((RaycastHit)(ref val3)).point, ref val4, _navMeshSampleDistance, -1)) { position = ((NavMeshHit)(ref val4)).position; return true; } } position = Vector3.zero; return false; } public static bool TryGetPositionInDirection(Vector3 origin, Vector3 direction, float minDistance, float maxDistance, out Vector3 position) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0034: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //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) RaycastHit val2 = default(RaycastHit); NavMeshHit val3 = default(NavMeshHit); for (int i = 0; i < _attempts; i++) { float num = Random.Range(minDistance, maxDistance); Vector3 val = origin + ((Vector3)(ref direction)).normalized * num + Vector3.up * _raycastHeight; if (Physics.Raycast(val, Vector3.down, ref val2, _raycastLength) && NavMesh.SamplePosition(((RaycastHit)(ref val2)).point, ref val3, _navMeshSampleDistance, -1)) { position = ((NavMeshHit)(ref val3)).position; return true; } } position = Vector3.zero; return false; } } internal static class PlayerHelper { public static void Initialize() { Events.OnKilledByEnemy += HandleKilledByEnemy; Events.OnKilledByPhysGrabObject += HandleKilledByPhysGrabObject; Events.OnKilledByExplosion += HandleKilledByExplosion; Application.quitting += delegate { Events.OnKilledByEnemy -= HandleKilledByEnemy; Events.OnKilledByPhysGrabObject -= HandleKilledByPhysGrabObject; Events.OnKilledByExplosion -= HandleKilledByExplosion; }; } public static PlayerAvatar GetLocalPlayer() { return PlayerAvatar.instance; } public static bool TryGetLocalPlayer(out PlayerAvatar playerAvatar) { playerAvatar = GetLocalPlayer(); return (Object)(object)playerAvatar != (Object)null; } public static bool IsLocalPlayerAlive() { if (TryGetLocalPlayer(out var playerAvatar)) { return !playerAvatar.deadSet; } return false; } public static bool AnyPlayersNearby(Vector3 origin, float radius) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GameDirector.instance == (Object)null) { return false; } foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if (!player.deadSet && Vector3.Distance(origin, ((Component)player).transform.position) <= radius) { return true; } } return false; } public static void PlayerTumble(PlayerAvatar playerAvatar, float time = 2f) { if (!((Object)(object)playerAvatar == (Object)null) && !playerAvatar.isDisabled) { if (!playerAvatar.tumble.isTumbling) { playerAvatar.tumble.TumbleRequest(true, false); } playerAvatar.tumble.TumbleOverrideTime(time); } } private static void HandleKilledByEnemy(EnemyParent enemyParent) { if (EnemyManager.TryGetViewerData(enemyParent, out var viewerData)) { DeathMessage.Instance?.Show(enemyParent, viewerData); } } private static void HandleKilledByPhysGrabObject(PhysGrabObject physGrabObject) { Metadata val = default(Metadata); ViewerData viewerData = default(ViewerData); if (ComponentExtensions.TryGetMetadata((Component)(object)physGrabObject, ref val, true) && val.TryGet("ViewerData", ref viewerData)) { DeathMessage.Instance?.Show(physGrabObject, viewerData); } } private static void HandleKilledByExplosion(Metadata metadata) { ViewerData viewerData = default(ViewerData); if (metadata.TryGet("ViewerData", ref viewerData)) { string sourceName = metadata.Get("Name", (string)null); DeathMessage.Instance?.ShowForExplosion(viewerData, sourceName); } } } internal static class ValuableHelper { public static PrefabRef GetValuableByName(string name) { return ((IEnumerable)Valuables.AllValuables).FirstOrDefault((Func)((PrefabRef x) => x.PrefabName == name)); } public static bool TryGetValuableByName(string name, out PrefabRef prefabRef) { prefabRef = GetValuableByName(name); return prefabRef != null; } } } namespace com.github.zehsteam.TwitchTrolling.Extensions { internal static class CollectionExtensions { public static EnemyConfigEntry GetRandom(this IEnumerable list) { if (list == null || !list.Any()) { return null; } EnemyConfigEntry[] array = list.ToArray(); return array[Random.Range(0, array.Length)]; } public static bool TryGetRandom(this IEnumerable list, out EnemyConfigEntry enemyConfigEntry) { enemyConfigEntry = list.GetRandom(); return enemyConfigEntry != null; } public static bool AddSingleInstance(this List list, T item) { if (list == null || item == null) { return false; } if (!list.Contains(item)) { list.Add(item); return true; } return false; } public static List GetMissingFrom(this List list, List other) { if (list == null || other == null) { return new List(); } return list.Where((T x) => !other.Contains(x)).ToList(); } public static void RemoveAll(this List list, List objectsToRemove) { if (list == null || list.Count == 0 || objectsToRemove == null) { return; } foreach (T item in objectsToRemove) { if (item != null) { list.Remove(item); } } } public static IEnumerable SortByShortest(this IEnumerable list) { return list.OrderBy((string s) => s?.Length ?? 0); } public static IEnumerable SortByLongest(this IEnumerable list) { IEnumerable enumerable = list.SortByShortest(); enumerable.Reverse(); return enumerable; } } internal static class ComponentExtensions { public static bool TryGetComponentInParent(this Component component, out T result) where T : Component { if ((Object)(object)component == (Object)null) { result = default(T); return false; } result = component.GetComponentInParent(); return (Object)(object)result != (Object)null; } public static T GetComponentInParents(this Component component) where T : Component { if ((Object)(object)component == (Object)null) { return default(T); } Transform parent = component.transform.parent; T result = default(T); while ((Object)(object)parent != (Object)null) { if (((Component)parent).TryGetComponent(ref result)) { return result; } parent = parent.parent; } return default(T); } public static bool TryGetComponentInParents(this Component component, out T result) where T : Component { result = component.GetComponentInParents(); return (Object)(object)result != (Object)null; } public static void SetViewerMetadata(this Component component, ViewerData viewerData) { if (!((Object)(object)component == (Object)null) && viewerData != null) { component.gameObject.SetViewerMetadata(viewerData); } } } internal static class ConfigEntryExtensions { public static bool SetValue(this ConfigEntry configEntry, string value) { if (configEntry == null) { return false; } try { Type typeFromHandle = typeof(T); if ((object)typeFromHandle != null) { Type type = typeFromHandle; object obj; if (type == typeof(int) && int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result)) { obj = result; } else { Type type2 = typeFromHandle; if (type2 == typeof(float) && float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { obj = result2; } else { Type type3 = typeFromHandle; if (type3 == typeof(double) && double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { obj = result3; } else { Type type4 = typeFromHandle; if (type4 == typeof(bool) && bool.TryParse(value, out var result4)) { obj = result4; } else { Type type5 = typeFromHandle; if (type5 == typeof(string)) { obj = value; } else { Type type6 = typeFromHandle; if (!type6.IsEnum || !Enum.TryParse(type6, value, ignoreCase: true, out object result5)) { goto IL_0127; } obj = result5; } } } } } object obj2 = obj; configEntry.Value = (T)obj2; return true; } goto IL_0127; IL_0127: throw new NotSupportedException($"Unsupported config type: {typeof(T)}"); } catch (Exception ex) { Logger.LogError("SetValue failed for key '" + ((ConfigEntryBase)configEntry).Definition.Key + "': " + ex.Message); return false; } } } internal static class ConfigFileExtensions { public static ConfigEntry Bind(this ConfigFile configFile, string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown return configFile.Bind(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty())); } public static Dictionary GetConfigEntries(this ConfigFile configFile) { if (configFile == null) { return new Dictionary(); } if (!(typeof(ConfigFile).GetField("Entries", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(configFile) is Dictionary dictionary)) { return new Dictionary(); } Dictionary dictionary2 = new Dictionary(); foreach (KeyValuePair item in dictionary) { dictionary2[item.Key] = item.Value.BoxedValue?.ToString(); } return dictionary2; } public static Dictionary GetOrphanedConfigEntries(this ConfigFile configFile) { if (configFile == null) { return new Dictionary(); } return (((object)configFile).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(configFile, null) as Dictionary) ?? new Dictionary(); } public static bool RemoveOrphaned(this ConfigFile configFile, ConfigDefinition configDefinition) { if (configFile == null || configDefinition == (ConfigDefinition)null) { return false; } if (typeof(ConfigFile).GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(configFile) is IDictionary dictionary) { return dictionary.Remove(configDefinition); } return false; } public static bool MigrateConfigEntry(this ConfigFile configFile, ConfigDefinition oldConfigDefinition, string value, ConfigEntry newConfigEntry) { if (configFile == null || oldConfigDefinition == (ConfigDefinition)null || newConfigEntry == null) { return false; } configFile.RemoveOrphaned(oldConfigDefinition); return newConfigEntry.SetValue(value); } } internal static class EnemySetupExtensions { private static readonly Dictionary _enemySetupEnemyNamePairs = new Dictionary(); public static bool TryGetEnemyName(this EnemySetup enemySetup, out string enemyName) { if (_enemySetupEnemyNamePairs.TryGetValue(enemySetup, out var value)) { enemyName = value; return true; } List list = new List(); EnemyParent val = default(EnemyParent); foreach (PrefabRef spawnObject in enemySetup.spawnObjects) { GameObject prefab = spawnObject.Prefab; if (!((Object)(object)prefab == (Object)null) && prefab.TryGetComponent(ref val)) { list.Add(val.enemyName); } } if (list.Count == 0) { enemyName = string.Empty; return false; } string firstEnemyName = list[0]; if (list.All((string x) => x == firstEnemyName)) { enemyName = firstEnemyName; if (!_enemySetupEnemyNamePairs.ContainsKey(enemySetup)) { _enemySetupEnemyNamePairs.Add(enemySetup, enemyName); } return true; } Logger.LogError("EnemySetupExtensions: Failed to get enemy name from EnemySetup. EnemySetup '" + ((Object)enemySetup).name + "' contains spawn objects that do not all share the same enemy name! (" + string.Join(", ", list) + ")"); enemyName = string.Empty; return false; } public static string GetEnemyName(this EnemySetup enemySetup) { if (enemySetup.TryGetEnemyName(out var enemyName)) { return enemyName; } return string.Empty; } } internal static class GameObjectExtensions { public static void SetViewerMetadata(this GameObject gameObject, ViewerData viewerData) { if (!((Object)(object)gameObject == (Object)null) && viewerData != null) { Metadata orCreateMetadata = GameObjectExtensions.GetOrCreateMetadata(gameObject); orCreateMetadata.Set("ViewerData", viewerData); string text = string.Empty; ValuableObject val = default(ValuableObject); if (gameObject.TryGetComponent(ref val)) { text = ((Object)gameObject).name.TrimStart("Valuable "); } ItemAttributes val2 = default(ItemAttributes); if (gameObject.TryGetComponent(ref val2)) { text = val2.itemName; } Enemy val3 = default(Enemy); if (gameObject.TryGetComponent(ref val3)) { text = val3.EnemyParent.enemyName; } if (string.IsNullOrEmpty(text)) { text = ((Object)gameObject).name; } text = text.TrimEnd("(Clone)").Trim(); orCreateMetadata.Set("Name", text); } } } internal static class HurtColliderExtensions { public static Enemy GetEnemy(this HurtCollider hurtCollider) { if ((Object)(object)hurtCollider == (Object)null) { return null; } return hurtCollider.enemyHost; } public static bool TryGetEnemy(this HurtCollider hurtCollider, out Enemy enemy) { enemy = hurtCollider.GetEnemy(); return (Object)(object)enemy != (Object)null; } public static EnemyParent GetEnemyParent(this HurtCollider hurtCollider) { if (hurtCollider.TryGetEnemy(out var enemy)) { return ((Component)(object)enemy).GetComponentInParents(); } return null; } public static bool TryGetEnemyParent(this HurtCollider hurtCollider, out EnemyParent enemyParent) { enemyParent = hurtCollider.GetEnemyParent(); return (Object)(object)enemyParent != (Object)null; } } internal static class ImageExtensions { public static void SetAlpha(this Image image, int value) { //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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)image == (Object)null)) { Color32 val = Color32.op_Implicit(((Graphic)image).color); val.a = (byte)Mathf.Clamp(value, 0, 255); ((Graphic)image).color = Color32.op_Implicit(val); } } } internal static class ReflectionExtensions { public static IEnumerable SafeGetMethods(this Type type) { try { return type.GetMethods(); } catch { return Array.Empty(); } } public static T SafeGetCustomAttribute(this MemberInfo member) where T : Attribute { try { return member.GetCustomAttribute(); } catch { return null; } } public static bool HasCustomAttribute(this MemberInfo member) where T : Attribute { try { return member.GetCustomAttribute() != null; } catch { return false; } } } internal static class StringExtensions { public static string TrimStart(this string s, string str) { if (s != null && str != null && s.StartsWith(str)) { return s.Substring(str.Length); } return s; } public static string TrimEnd(this string s, string str) { if (s != null && str != null && s.EndsWith(str)) { return s.Substring(0, s.Length - str.Length); } return s; } public static string RichColor(this string s, string colorHex) { return "" + s + ""; } public static string RichSize(this string s, int size) { return $"{s}"; } } internal static class TwitchUserExtensions { public static string GetDisplayNameWithColor(this TwitchUser twitchUser) { return Utils.GetTextWithReadableColor(((TwitchUser)(ref twitchUser)).DisplayName, ((TwitchUser)(ref twitchUser)).Color); } } } namespace com.github.zehsteam.TwitchTrolling.Dependencies { internal static class MoreHeadProxy { public const string PLUGIN_GUID = "Mhz.REPOMoreHead"; private static bool? _enabled; public static bool Enabled { get { bool valueOrDefault = _enabled.GetValueOrDefault(); if (!_enabled.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("Mhz.REPOMoreHead"); _enabled = valueOrDefault; } return _enabled.Value; } } } internal static class SpawnManagerProxy { public const string PLUGIN_GUID = "soundedsquash.spawnmanager"; private static bool? _enabled; public static bool Enabled { get { bool valueOrDefault = _enabled.GetValueOrDefault(); if (!_enabled.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("soundedsquash.spawnmanager"); _enabled = valueOrDefault; } return _enabled.Value; } } } } namespace com.github.zehsteam.TwitchTrolling.Dependencies.REPOConfigMod { internal static class REPOConfigHelper { [CompilerGenerated] private sealed class d__1 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string modName; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; ConfigMenu.CreateModMenu(); <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; REPOPopupPage popupPageByObjectName = GetPopupPageByObjectName("Menu Page Mods"); if ((Object)(object)popupPageByObjectName == (Object)null) { return false; } REPOInputField inputFieldByObjectName = GetInputFieldByObjectName(popupPageByObjectName, "Input Field - Mod Search"); string text = ConfigMenu.FixNaming(modName); if (inputFieldByObjectName != null) { inputFieldByObjectName.inputStringSystem.SetValue(text, true); } GetModButton(text, fixNaming: false)?.onClick?.Invoke(); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static void OpenSettingsMenu(string modName) { CoroutineRunner.Start(OpenSettingsMenu_Coroutine(modName)); } [IteratorStateMachine(typeof(d__1))] private static IEnumerator OpenSettingsMenu_Coroutine(string modName) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0) { modName = modName }; } private static REPOPopupPage GetPopupPageByObjectName(string name) { return ((IEnumerable)REPOPopupPageLifetime.Instances).FirstOrDefault((Func)((REPOPopupPage x) => ((Object)((Component)x).gameObject).name.Equals(name, StringComparison.OrdinalIgnoreCase))); } private static REPOInputField GetInputFieldByObjectName(REPOPopupPage page, string name) { if ((Object)(object)page == (Object)null) { return null; } REPOInputField[] componentsInChildren = ((Component)page).GetComponentsInChildren(); return ((IEnumerable)componentsInChildren).FirstOrDefault((Func)((REPOInputField x) => ((Object)((Component)x).gameObject).name.Equals(name, StringComparison.OrdinalIgnoreCase))); } private static REPOButton GetModButton(string name, bool fixNaming = true) { if (fixNaming) { name = ConfigMenu.FixNaming(name); } return ((IEnumerable)ConfigMenu.currentModButtons).FirstOrDefault((Func)((REPOButton x) => ((TMP_Text)x.labelTMP).text.Equals(name, StringComparison.OrdinalIgnoreCase))); } } } namespace com.github.zehsteam.TwitchTrolling.Dependencies.MenuLibMod.Patches { [HarmonyPatch(typeof(REPOPopupPage))] internal static class REPOPopupPage_Patches { [HarmonyPatch("Awake")] [HarmonyPrefix] private static void Awake_Patch(REPOPopupPage __instance) { ((Component)__instance).gameObject.AddComponent(); } } } namespace com.github.zehsteam.TwitchTrolling.Dependencies.MenuLibMod.MonoBehaviours { public class REPOPopupPageLifetime : MonoBehaviour { private static readonly List _instances = new List(); private REPOPopupPage _page; public static IReadOnlyList Instances => _instances; public REPOPopupPage Page { get { if (_page == null) { _page = ((Component)this).GetComponent(); } return _page; } } private void OnEnable() { if (!_instances.Contains(Page)) { _instances.Add(Page); } } private void OnDisable() { _instances.Remove(Page); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }