using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using AngryLevelLoader; using AngryLevelLoader.Containers; using AngryLevelLoader.DataTypes; using AngryLevelLoader.DataTypes.MapVarHandlers; using AngryLevelLoader.Extensions; using AngryLevelLoader.Fields; using AngryLevelLoader.Managers; using AngryLevelLoader.Managers.BannedMods; using AngryLevelLoader.Managers.LegacyPatches; using AngryLevelLoader.Managers.ServerManager; using AngryLevelLoader.Notifications; using AngryLevelLoader.Notifications.SubNotifications; using AngryLevelLoader.Patches; using AngryLevelLoader.UserInterface; using AngryLevelLoader.Utils; using AngryUiComponents; using BananaDifficulty; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using BillionDifficulty; using Configgy; using FasterPunch; using HarmonyLib; using Logic; using LucasMeshCombine; using Newtonsoft.Json; using Notiffy.API; using PluginConfig; using PluginConfig.API; using PluginConfig.API.Decorators; using PluginConfig.API.Fields; using PluginConfig.API.Functionals; using ProjectProphet; using RudeLevelScript; using RudeLevelScripts; using RudeLevelScripts.Essentials; using Steamworks; using Steamworks.Data; using TMPro; using The_Timestopper; using TimeStop; using ULTRAKILL.Portal; using Ultracoins; using Ultrapain; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets.ResourceLocators; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Utilities; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityExplorer.ObjectExplorer; using UnityExplorer.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("AngryLevelLoader")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Loads level made with Rude level editor")] [assembly: AssemblyFileVersion("4.0.4.0")] [assembly: AssemblyInformationalVersion("4.0.4+3560ceecf45b141c239f8eb6f8b50cb6e50e3a20")] [assembly: AssemblyProduct("AngryLevelLoader")] [assembly: AssemblyTitle("AngryLevelLoader")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.0.4.0")] [module: UnverifiableCode] internal class CrossThreadInvoker : ISynchronizeInvoke { private class BackgroundUpdater : MonoBehaviour { public void Update() { ProcessQueue(); } } private class AsyncResult : IAsyncResult { public Delegate method; public object[] args; public ManualResetEvent manualResetEvent; public Thread invokingThread; public bool IsCompleted { get; set; } public WaitHandle AsyncWaitHandle => manualResetEvent; public object AsyncState { get; set; } public bool CompletedSynchronously { get; set; } public void Invoke() { AsyncState = method.DynamicInvoke(args); IsCompleted = true; manualResetEvent.Set(); } } private static CrossThreadInvoker instance; private static Thread mainThread; private static readonly Queue ToExecute = new Queue(); public static CrossThreadInvoker Instance => instance; public bool InvokeRequired => mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId; public static void Init() { if (instance == null) { mainThread = Thread.CurrentThread; instance = new CrossThreadInvoker(); ((Component)Plugin.instance).gameObject.AddComponent(); } } private static void ProcessQueue() { if (Thread.CurrentThread != mainThread) { throw new Exception("must be called from the same thread it was created on (created on thread id: " + mainThread.ManagedThreadId + ", called from thread id: " + Thread.CurrentThread.ManagedThreadId); } AsyncResult asyncResult = null; while (true) { lock (ToExecute) { if (ToExecute.Count == 0) { break; } asyncResult = ToExecute.Dequeue(); } asyncResult.Invoke(); } } public IAsyncResult BeginInvoke(Delegate method, object[] args) { AsyncResult asyncResult = new AsyncResult { method = method, args = args, IsCompleted = false, manualResetEvent = new ManualResetEvent(initialState: false), invokingThread = Thread.CurrentThread }; if (mainThread.ManagedThreadId != asyncResult.invokingThread.ManagedThreadId) { lock (ToExecute) { ToExecute.Enqueue(asyncResult); } } else { asyncResult.Invoke(); asyncResult.CompletedSynchronously = true; } return asyncResult; } public object EndInvoke(IAsyncResult result) { if (!result.IsCompleted) { result.AsyncWaitHandle.WaitOne(); } return result.AsyncState; } public object Invoke(Delegate method, object[] args) { if (InvokeRequired) { IAsyncResult result = BeginInvoke(method, args); return EndInvoke(result); } return method.DynamicInvoke(args); } } namespace AngryLevelLoader { public static class AngryPaths { internal enum Repo { AngryLevelLoader, AngryLevels } public const string SERVER_ROOT_GLOBAL = "https://angry.dnzsoft.com"; public const string SERVER_ROOT_LOCAL = "http://localhost:3000"; public static string SERVER_ROOT { get { if (!ConfigManager.useLocalServer.value) { return "https://angry.dnzsoft.com"; } return "http://localhost:3000"; } } public static string ConfigFolderPath => Path.Combine(Paths.ConfigPath, "AngryLevelLoader"); public static string OnlineCacheFolderPath => Path.Combine(ConfigFolderPath, "OnlineCache"); public static string ThumbnailCachePath => Path.Combine(OnlineCacheFolderPath, "thumbnailCacheHashes.txt"); internal static string LevelCatalogV1CachePath => Path.Combine(OnlineCacheFolderPath, "LevelCatalog.json"); public static string LevelCatalogCachePath => Path.Combine(OnlineCacheFolderPath, "V2", "LevelCatalog.json"); public static string ScriptsPath => Path.Combine(Plugin.workingDir, "Scripts"); public static string ScriptCatalogCachePath => Path.Combine(OnlineCacheFolderPath, "ScriptCatalog.json"); public static string ThumbnailCacheFolderPath => Path.Combine(OnlineCacheFolderPath, "ThumbnailCache"); public static string LastPlayedMapPath => Path.Combine(ConfigFolderPath, "lastPlayedMap.txt"); public static string LastUpdateMapPath => Path.Combine(ConfigFolderPath, "lastUpdateMap.txt"); internal static string GetGithubURL(Repo repo, string path) { string text = "release"; if (ConfigManager.useDevelopmentBranch.value) { text = "dev"; } string text2 = "AngryLevels"; switch (repo) { case Repo.AngryLevels: text2 = "AngryLevels"; break; case Repo.AngryLevelLoader: text2 = "AngryLevelLoader"; break; } return "https://raw.githubusercontent.com/eternalUnion/" + text2 + "/" + text + "/" + path; } internal static void TryCreateAllPaths() { AngryIOUtils.TryCreateDirectory(ConfigFolderPath); AngryIOUtils.TryCreateDirectory(OnlineCacheFolderPath); AngryIOUtils.TryCreateDirectory(ThumbnailCacheFolderPath); AngryIOUtils.TryCreateDirectory(ScriptsPath); } } internal class SpaceField : CustomConfigField { public SpaceField(ConfigPanel parentPanel, float space) : base(parentPanel, 60f, space) { } } [BepInPlugin("com.eternalUnion.angryLevelLoader", "AngryLevelLoader", "4.0.4")] [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.*/)] [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.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PLUGIN_NAME = "AngryLevelLoader"; public const string PLUGIN_GUID = "com.eternalUnion.angryLevelLoader"; public const string PLUGIN_VERSION = "4.0.4"; public const string PLUGIN_CONFIG_MIN_VERSION = "1.8.0"; internal static string workingDir; public static string tempFolderPath; internal static string dataPath; internal static string levelsPath; internal static string mapVarsFolderPath; public static string angryCatalogPath; internal static Plugin instance; internal static Harmony harmony; internal static ManualLogSource logger; private static readonly Dictionary angryBundles = new Dictionary(); private static int numOfOldBundles = 0; internal static FileSystemWatcher levelsWatcher; internal static FileSystemWatcher scriptsWatcher; private float lastPress; public static IEnumerable GetAllBundleContainers() { return angryBundles.Values; } public static bool TryGetAngryBundleByGuid(string guid, out BundleContainer bundleContainer) { bundleContainer = angryBundles.Values.Where((BundleContainer bundle) => bundle.bundleGuid == guid).FirstOrDefault(); return bundleContainer != null; } public static bool TryGetAngryLevel(string id, out LevelContainer level) { level = null; foreach (BundleContainer allBundleContainer in GetAllBundleContainers()) { foreach (LevelContainer allLevelContainer in allBundleContainer.GetAllLevelContainers()) { if (allLevelContainer.levelId == id) { level = allLevelContainer; return true; } } } return false; } private static void ProcessPath(string path, FolderButtonField folder) { if (AngryFileUtils.TryGetAngryBundleData(path, out var data, out var error)) { if (angryBundles.TryGetValue(data.bundleGuid, out var value)) { if (value.HasValidAngryFile && !AngryIOUtils.PathEquals(path, value.pathToAngryBundle)) { logger.LogError((object)("Duplicate angry files. Original: " + Path.GetFileName(value.pathToAngryBundle) + ". Duplicate: " + Path.GetFileName(path))); if (!string.IsNullOrEmpty(ConfigManager.errorText.text)) { ConfigHeader errorText = ConfigManager.errorText; errorText.text += "\n"; } ConfigHeader errorText2 = ConfigManager.errorText; errorText2.text = errorText2.text + "Error loading " + Path.GetFileName(path) + " Duplicate file, original is " + Path.GetFileName(value.pathToAngryBundle); return; } folder.bundles.Add(value); if (data.bundleVersion < 6) { numOfOldBundles++; } value.pathToAngryBundle = path; if (!value.LazyLoaded) { try { value.ReloadBundle(forceReload: false, lazyLoad: true); } catch (Exception arg) { logger.LogWarning((object)$"Exception thrown while loading level bundle: {arg}"); if (!string.IsNullOrEmpty(ConfigManager.errorText.text)) { ConfigHeader errorText3 = ConfigManager.errorText; errorText3.text += "\n"; } ConfigHeader errorText4 = ConfigManager.errorText; errorText4.text = errorText4.text + "Error loading " + Path.GetFileNameWithoutExtension(path) + ". Check the logs for more information"; } } if (value.LazyLoaded && value.BuildHash != data.buildHash) { if (value.Loaded && AngrySceneManager.isInCustomLevel && AngrySceneManager.currentBundleContainer == value) { value.FileChanged(); } else { value.ReloadBundle(forceReload: false, lazyLoad: true); } } return; } value = new BundleContainer(path, data); angryBundles[data.bundleGuid] = value; folder.bundles.Add(value); try { value.ReloadBundle(forceReload: false, lazyLoad: true); } catch (Exception arg2) { logger.LogWarning((object)$"Exception thrown while loading level bundle: {arg2}"); if (!string.IsNullOrEmpty(ConfigManager.errorText.text)) { ConfigHeader errorText5 = ConfigManager.errorText; errorText5.text += "\n"; } ConfigHeader errorText6 = ConfigManager.errorText; errorText6.text = errorText6.text + "Error loading " + Path.GetFileNameWithoutExtension(path) + ". Check the logs for more information"; } if (data.bundleVersion < 6) { numOfOldBundles++; } } else if (AngryFileUtils.IsV1LegacyFile(path)) { if (!string.IsNullOrEmpty(ConfigManager.errorText.text)) { ConfigHeader errorText7 = ConfigManager.errorText; errorText7.text += "\n"; } ConfigHeader errorText8 = ConfigManager.errorText; errorText8.text = errorText8.text + "" + Path.GetFileName(path) + " is a V1 legacy file. Support for legacy files were dropped after 2.5.0"; } else { logger.LogError((object)$"Could not load the bundle at {path}\n{error}"); if (!string.IsNullOrEmpty(ConfigManager.errorText.text)) { ConfigHeader errorText9 = ConfigManager.errorText; errorText9.text += "\n"; } ConfigHeader errorText10 = ConfigManager.errorText; errorText10.text = errorText10.text + "Failed to load " + Path.GetFileNameWithoutExtension(path) + ""; } } private static void ScanForLevelsRecursive(string folderPath, FolderButtonField folder) { string[] files = Directory.GetFiles(folderPath); foreach (string text in files) { if (text.EndsWith(".angry")) { ProcessPath(Path.Combine(folderPath, text), folder); } } files = Directory.GetDirectories(folderPath); foreach (string obj in files) { string fileName = Path.GetFileName(obj); ScanForLevelsRecursive(obj, folder.GetOrCreateFolder(fileName)); } } public static void ScanForLevels() { numOfOldBundles = 0; ConfigManager.errorText.text = ""; ConfigManager.searchBar.value = ""; if (!Directory.Exists(levelsPath)) { logger.LogWarning((object)("Could not find the Levels folder at " + levelsPath)); ConfigManager.errorText.text = "Error: Levels folder not found"; return; } AngryBundleList.ResetFolders(); ScanForLevelsRecursive(levelsPath, AngryBundleList.rootFolder); AngryBundleList.SortBundles(); AngryBundleList.UpdateFolderIcons(); if (numOfOldBundles != 0) { if (!string.IsNullOrEmpty(ConfigManager.errorText.text)) { ConfigHeader errorText = ConfigManager.errorText; errorText.text += "\n"; } ConfigHeader errorText2 = ConfigManager.errorText; errorText2.text += $"Hidden {numOfOldBundles} old angry file(s). These files can be deleted at the bottom of the settings page."; } AngryBundleList.DisplayFolder(AngryBundleList.rootFolder); OnlineLevelsList.UpdateUI(); } private static bool LoadEssentialScripts() { bool result = true; switch (ScriptManager.AttemptLoadScriptWithCertificate("AngryLoaderAPI.dll")) { case ScriptManager.LoadScriptResult.NotFound: logger.LogError((object)"Required script AngryLoaderAPI.dll not found"); result = false; break; case ScriptManager.LoadScriptResult.NoCertificate: logger.LogError((object)"Required script AngryLoaderAPI.dll is not signed"); result = false; break; case ScriptManager.LoadScriptResult.InvalidCertificate: logger.LogError((object)"Required script AngryLoaderAPI.dll signature is invalid"); result = false; break; default: logger.LogError((object)"Required script AngryLoaderAPI.dll could not be loaded"); result = false; break; case ScriptManager.LoadScriptResult.Loaded: break; } switch (ScriptManager.AttemptLoadScriptWithCertificate("RudeLevelScripts.dll")) { case ScriptManager.LoadScriptResult.NotFound: logger.LogError((object)"Required script RudeLevelScripts.dll not found"); result = false; break; case ScriptManager.LoadScriptResult.NoCertificate: logger.LogError((object)"Required script RudeLevelScripts.dll is not signed"); result = false; break; case ScriptManager.LoadScriptResult.InvalidCertificate: logger.LogError((object)"Required script RudeLevelScripts.dll signature is invalid"); result = false; break; default: logger.LogError((object)"Required script RudeLevelScripts.dll could not be loaded"); result = false; break; case ScriptManager.LoadScriptResult.Loaded: break; } return result; } private void ForceLoadAddressableDependencies() { //IL_0005: 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) //IL_0018: 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_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_003e: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_008f: 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_00a2: Unknown result type (might be due to invalid IL or missing references) Addressables.LoadAssetAsync((object)"Assets/Prefabs/Attacks and Projectiles/Projectile Decorative.prefab").WaitForCompletion(); Addressables.LoadAssetAsync((object)"FirstRoom").WaitForCompletion(); Addressables.LoadAssetAsync((object)"FirstRoom Secret").WaitForCompletion(); Addressables.LoadAssetAsync((object)"FirstRoom Prime").WaitForCompletion(); Addressables.LoadAssetAsync((object)"Assets/Prefabs/Levels/Special Rooms/FirstRoom Encore.prefab").WaitForCompletion(); Addressables.LoadAssetAsync((object)"Assets/Fonts/VCR_OSD_MONO_1.001.ttf").WaitForCompletion(); Addressables.LoadAssetAsync((object)"Assets/Textures/UI/meter.png").WaitForCompletion(); Addressables.LoadAssetAsync((object)"Assets/Textures/UI/arrow.png").WaitForCompletion(); Addressables.LoadAssetAsync((object)"Assets/Materials/Environment/Metal/Metal Decoration 20.mat").WaitForCompletion(); } private static void RefreshCatalogOnMainMenu(Scene newScene, LoadSceneMode mode) { if (!(SceneHelper.CurrentScene != "Main Menu")) { if (ConfigManager.refreshCatalogOnBoot.value) { OnlineLevelsList.RefreshAsync(); } SceneManager.sceneLoaded -= RefreshCatalogOnMainMenu; } } private static void InitializeFileWatcher() { if (levelsWatcher != null) { return; } levelsWatcher = new FileSystemWatcher(levelsPath); levelsWatcher.SynchronizingObject = CrossThreadInvoker.Instance; levelsWatcher.Changed += delegate(object sender, FileSystemEventArgs e) { string fullPath = e.FullPath; foreach (BundleContainer value2 in angryBundles.Values) { if (AngryIOUtils.PathEquals(fullPath, value2.pathToAngryBundle)) { logger.LogWarning((object)("Bundle " + fullPath + " was updated, container notified")); value2.FileChanged(); break; } } }; levelsWatcher.Renamed += delegate(object sender, RenamedEventArgs e) { string oldFullPath = e.OldFullPath; foreach (BundleContainer value3 in angryBundles.Values) { if (AngryIOUtils.PathEquals(oldFullPath, value3.pathToAngryBundle)) { logger.LogWarning((object)("Bundle " + oldFullPath + " was renamed, path updated")); value3.pathToAngryBundle = e.FullPath; break; } } }; levelsWatcher.Deleted += delegate(object sender, FileSystemEventArgs e) { string fullPath = e.FullPath; foreach (BundleContainer value4 in angryBundles.Values) { if (AngryIOUtils.PathEquals(fullPath, value4.pathToAngryBundle)) { logger.LogWarning((object)("Bundle " + fullPath + " was deleted, unlinked")); value4.pathToAngryBundle = ""; break; } } }; levelsWatcher.Created += delegate(object sender, FileSystemEventArgs e) { string fullPath = e.FullPath; if (AngryFileUtils.TryGetAngryBundleData(fullPath, out var data, out var _) && angryBundles.TryGetValue(data.bundleGuid, out var value) && value.bundleGuid == data.bundleGuid && !value.HasValidAngryFile) { logger.LogWarning((object)("Bundle " + fullPath + " was just added, and a container with the same guid had no file linked. Linked, container notified")); value.pathToAngryBundle = fullPath; value.FileChanged(); } }; levelsWatcher.Filter = "*"; levelsWatcher.IncludeSubdirectories = true; levelsWatcher.EnableRaisingEvents = true; scriptsWatcher = new FileSystemWatcher(AngryPaths.ScriptsPath); scriptsWatcher.SynchronizingObject = CrossThreadInvoker.Instance; scriptsWatcher.Changed += delegate(object sender, FileSystemEventArgs e) { string fullPath = e.FullPath; if (fullPath.EndsWith(".dll") && ScriptManager.ScriptChanged(Path.GetFileName(fullPath))) { logger.LogMessage((object)("Detected script change " + Path.GetFileName(fullPath))); AngryUI.UpdatedScript = Path.GetFileName(fullPath); } }; scriptsWatcher.Filter = "*"; scriptsWatcher.IncludeSubdirectories = false; scriptsWatcher.EnableRaisingEvents = true; SceneManager.sceneLoaded += CheckForInstantLoad; static void CheckForInstantLoad(Scene scene, LoadSceneMode mode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)mode != 1 && !AngrySceneManager.isInCustomLevel && !(SceneHelper.CurrentScene != "Main Menu")) { if (!InternalConfigManager.instantLoadLevel.value) { SceneManager.sceneLoaded -= CheckForInstantLoad; } else { InternalConfigManager.instantLoadLevel.value = false; logger.LogInfo((object)"Starting custom level instantly"); ((MonoBehaviour)instance).StartCoroutine(LoadLevelInstantly()); } } } static IEnumerator LoadLevelInstantly() { yield return null; if (!TryGetAngryBundleByGuid(InternalConfigManager.instantLoadLevelGuid.value, out var bundle)) { logger.LogInfo((object)"Bundle not found"); } else { Task handler = bundle.ReloadBundle(forceReload: false, lazyLoad: false); yield return (object)new WaitUntil((Func)(() => handler.IsCompleted)); if (!bundle.TryGetLevelContainer(InternalConfigManager.instantLoadLevelId.value, out var level)) { logger.LogInfo((object)"Level not found"); } else { Scene activeScene = SceneManager.GetActiveScene(); GameObject val = (from obj in ((Scene)(ref activeScene)).GetRootGameObjects() where ((Object)obj).name == "Canvas" select obj).FirstOrDefault(); if ((Object)(object)val == (Object)null) { logger.LogWarning((object)"Angry tried to create main menu buttons, but root canvas was not found!"); } else { Transform optionsMenu = val.transform.Find("OptionsMenu"); if ((Object)(object)optionsMenu == (Object)null) { logger.LogError((object)"Angry tried to find the options menu but failed!"); } else { ((Component)optionsMenu).gameObject.SetActive(true); yield return null; Transform val2 = ((Component)optionsMenu).transform.Find("Navigation Rail/PluginConfiguratorButton(Clone)"); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)optionsMenu).transform.Find("Navigation Rail/PluginConfiguratorButton"); } if ((Object)(object)val2 == (Object)null) { logger.LogError((object)"Angry tried to find the plugin configurator button but failed!"); } else { Transform val3 = optionsMenu.Find("Navigation Rail"); ButtonHighlightParent val4 = default(ButtonHighlightParent); if ((Object)(object)val3 != (Object)null && ((Component)val3).gameObject.TryGetComponent(ref val4) && (val4.buttons == null || val4.buttons.Length == 0)) { val4.Start(); val4.targetOnStart = null; } ((UnityEvent)((Component)val2).gameObject.GetComponent