using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; [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("Skip_Intro")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Skip loading intro for GWYF")] [assembly: AssemblyTitle("Skip_Intro")] [assembly: AssemblyVersion("1.0.0.0")] [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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 Skip_Intro { [BepInPlugin("com.mister9982.gamblewithyourfriends.skipintro", "Skip Intro", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { [CompilerGenerated] private sealed class d__36 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Plugin <>4__this; public string reason; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__36(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown int num = <>1__state; Plugin plugin = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; plugin._queuedSkip = null; if (!IsActive) { return false; } if (!TrySkipCurrentIntro(reason)) { plugin._timeoutSkip = ((MonoBehaviour)plugin).StartCoroutine(plugin.TimeoutSkip(Mathf.Max(0f, plugin._skipTimeout.Value))); } 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__33 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Plugin <>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__33(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown int num = <>1__state; Plugin plugin = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; 5__2 = Time.realtimeSinceStartup + Mathf.Max(0f, plugin._startupFocusRetrySeconds.Value); break; case 1: <>1__state = -1; break; } if (IsActive && Time.realtimeSinceStartup < 5__2) { Application.runInBackground = true; if (plugin._forceWindowFocus.Value && !Application.isFocused) { StartupWindowFocus.TryBringCurrentProcessToFront(); } plugin.QueueSkip("startup retry"); <>2__current = (object)new WaitForSecondsRealtime(0.15f); <>1__state = 1; return true; } plugin._startupFocusAndSkip = 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(); } } [CompilerGenerated] private sealed class d__37 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float timeoutSeconds; public Plugin <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__37(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown int num = <>1__state; Plugin plugin = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSecondsRealtime(timeoutSeconds); <>1__state = 1; return true; case 1: <>1__state = -1; plugin._timeoutSkip = null; if (!IsActive) { return false; } Logger.LogWarning((object)$"Skip retry reached after {timeoutSeconds:0.###}s; trying startup setup again."); TrySkipCurrentIntro("timeout fallback"); 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 string PluginGuid = "com.mister9982.gamblewithyourfriends.skipintro"; public const string PluginName = "Skip Intro"; public const string PluginVersion = "1.0.0"; private const string MainMenuSceneName = "MainMenuScene"; private const string NetworkSetupSceneName = "NetworkSetupScene"; private const float StartupFocusRetryIntervalSeconds = 0.15f; private ConfigEntry _skipTimeout; private ConfigEntry _forceWindowFocus; private ConfigEntry _startupFocusRetrySeconds; private Harmony? _harmony; private Coroutine? _queuedSkip; private Coroutine? _timeoutSkip; private Coroutine? _startupFocusAndSkip; private bool _finished; private int _lastSkipFrame = -1; private bool _loadRequested; private bool _originalRunInBackground; private bool _runInBackgroundChanged; internal static ManualLogSource Logger { get; private set; } internal static Plugin Instance { get; private set; } internal static bool IsActive { get { if ((Object)(object)Instance != (Object)null) { return !Instance._finished; } return false; } } private void Awake() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) Instance = this; Logger = ((BaseUnityPlugin)this).Logger; BindConfig(); EnableStartupBackgroundExecution(); _harmony = new Harmony("com.mister9982.gamblewithyourfriends.skipintro"); SkipIntroPatcher.Apply(_harmony); SceneManager.sceneLoaded += OnSceneLoaded; _startupFocusAndSkip = ((MonoBehaviour)this).StartCoroutine(StartupFocusAndSkipRoutine()); Logger.LogInfo((object)"Skip Intro v1.0.0 loaded and initiated!"); HandleScene(SceneManager.GetActiveScene(), "initial scene"); } private void OnDestroy() { Finish("Plugin destroyed"); if (Instance == this) { Instance = null; } } private void BindConfig() { _skipTimeout = ((BaseUnityPlugin)this).Config.Bind("General", "SkipTimeoutSeconds", 0f, "Seconds to wait before retrying if the first skip attempt cannot find a load target."); _forceWindowFocus = ((BaseUnityPlugin)this).Config.Bind("General", "ForceWindowFocusOnStartup", true, "Bring the game window to the foreground during startup so splash skipping works without a click/key press."); _startupFocusRetrySeconds = ((BaseUnityPlugin)this).Config.Bind("General", "StartupFocusRetrySeconds", 8f, "How long to retry startup window focus while splash scenes are being skipped."); } private void OnSceneLoaded(Scene scene, LoadSceneMode _) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) HandleScene(scene, "scene loaded"); } private void HandleScene(Scene scene, string reason) { //IL_0007: 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) _loadRequested = false; if (IsNetworkSetupScene(scene)) { Finish("Network setup reached; game auth/startup flow is now running"); } else if (IsMainMenuScene(scene)) { Finish("Main menu reached; no auth changes were applied"); } else { QueueSkip(reason); } } [IteratorStateMachine(typeof(d__33))] private IEnumerator StartupFocusAndSkipRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__33(0) { <>4__this = this }; } internal static void QueueSkipFromPatch(string reason) { if (IsActive) { Instance.QueueSkip(reason); } } private void QueueSkip(string reason) { if (IsActive && !_loadRequested) { StopRunningCoroutine(ref _queuedSkip); StopRunningCoroutine(ref _timeoutSkip); _queuedSkip = ((MonoBehaviour)this).StartCoroutine(SkipAfterFrameEnd(reason)); } } [IteratorStateMachine(typeof(d__36))] private IEnumerator SkipAfterFrameEnd(string reason) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__36(0) { <>4__this = this, reason = reason }; } [IteratorStateMachine(typeof(d__37))] private IEnumerator TimeoutSkip(float timeoutSeconds) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__37(0) { <>4__this = this, timeoutSeconds = timeoutSeconds }; } internal static bool TrySkipCurrentIntro(string reason) { //IL_0017: 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_001d: 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_0071: 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_0087: Unknown result type (might be due to invalid IL or missing references) if (!IsActive) { return false; } if (Instance._loadRequested) { return true; } Scene activeScene = SceneManager.GetActiveScene(); if (IsNetworkSetupScene(activeScene)) { Instance.Finish("Network setup already active"); return true; } if (IsMainMenuScene(activeScene)) { Instance.Finish("Main menu already active"); return true; } if (Instance._lastSkipFrame == Time.frameCount) { return true; } Instance._lastSkipFrame = Time.frameCount; if (TryLoadNetworkSetupDirectly(activeScene, reason)) { return true; } if (TryLoadNextBuildIndex(activeScene, reason)) { return true; } if (TryUseGameSceneSkipper(activeScene, reason)) { return true; } Logger.LogWarning((object)("Cannot skip '" + ((Scene)(ref activeScene)).name + "': no valid startup scene target found.")); return false; } private static bool TryLoadNetworkSetupDirectly(Scene active, string reason) { if (!Application.CanStreamedLevelBeLoaded("NetworkSetupScene")) { return false; } Instance._loadRequested = true; Logger.LogInfo((object)("Loading 'NetworkSetupScene' directly from '" + ((Scene)(ref active)).name + "'. Reason: " + reason)); SceneManager.LoadScene("NetworkSetupScene"); return true; } private static bool TryLoadNextBuildIndex(Scene active, string reason) { checked { int num = ((Scene)(ref active)).buildIndex + 1; if ((uint)num >= (uint)SceneManager.sceneCountInBuildSettings) { return false; } Instance._loadRequested = true; Logger.LogInfo((object)$"Advancing from '{((Scene)(ref active)).name}' to build index {num}. Reason: {reason}"); SceneManager.LoadScene(num); return true; } } private static bool TryUseGameSceneSkipper(Scene active, string reason) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) var (type, methodInfo) = SkipIntroPatcher.CachedSceneSkipper; if (type == null || methodInfo == null) { return false; } Object[] array = Resources.FindObjectsOfTypeAll(type); foreach (Object val in array) { if (BelongsToScene(val, active)) { SkipIntroPatcher.PrepareSceneSkipper(val); Instance._loadRequested = true; methodInfo.Invoke(val, Array.Empty()); Logger.LogInfo((object)("Skipped '" + ((Scene)(ref active)).name + "' via SceneSkipper. Reason: " + reason)); return true; } } return false; } internal void Finish(string reason) { if (!_finished) { _finished = true; SceneManager.sceneLoaded -= OnSceneLoaded; StopRunningCoroutine(ref _queuedSkip); StopRunningCoroutine(ref _timeoutSkip); StopRunningCoroutine(ref _startupFocusAndSkip); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; RestoreRunInBackground(); Logger.LogInfo((object)(reason + ". Intro patches removed.")); } } internal static bool IsMainMenuScene(Scene scene) { return string.Equals(((Scene)(ref scene)).name, "MainMenuScene", StringComparison.OrdinalIgnoreCase); } internal static bool IsNetworkSetupScene(Scene scene) { return string.Equals(((Scene)(ref scene)).name, "NetworkSetupScene", StringComparison.OrdinalIgnoreCase); } private static bool BelongsToScene(Object obj, Scene scene) { //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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) Component val = (Component)(object)((obj is Component) ? obj : null); Scene scene2; if (val == null) { GameObject val2 = (GameObject)(object)((obj is GameObject) ? obj : null); if (val2 != null) { scene2 = val2.scene; return ((Scene)(ref scene2)).handle == ((Scene)(ref scene)).handle; } return false; } scene2 = val.gameObject.scene; return ((Scene)(ref scene2)).handle == ((Scene)(ref scene)).handle; } private void StopRunningCoroutine(ref Coroutine? coroutine) { if (coroutine != null) { ((MonoBehaviour)this).StopCoroutine(coroutine); coroutine = null; } } private void EnableStartupBackgroundExecution() { _originalRunInBackground = Application.runInBackground; if (!_originalRunInBackground) { Application.runInBackground = true; _runInBackgroundChanged = true; } } private void RestoreRunInBackground() { if (_runInBackgroundChanged) { Application.runInBackground = _originalRunInBackground; _runInBackgroundChanged = false; } } } internal static class SkipIntroPatcher { [CompilerGenerated] private sealed class d__14 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public object skipper; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; if (!Plugin.IsActive) { return false; } PrepareSceneSkipper(skipper); Plugin.TrySkipCurrentIntro("SceneSkipper.SkipSceneRoutine"); 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 FieldInfo? _ignoreInputField; private static FieldInfo? _isSkippingField; private static FieldInfo? _transitionDurationField; private static readonly (string TypeName, string MethodName, string? Prefix, string? Postfix)[] PatchDefs = new(string, string, string, string)[4] { ("OfflineSplashCoinFlip", "Awake", "OfflineSplashCoinFlipAwakePrefix", null), ("SceneSkipper", "Start", "SceneSkipperStartPrefix", null), ("SceneSkipper", "OnSceneLoaded", null, "SceneSkipperOnSceneLoadedPostfix"), ("SceneSkipper", "SkipSceneRoutine", "SceneSkipperRoutinePrefix", null) }; internal static (Type? Type, MethodInfo? SkipScene) CachedSceneSkipper { get; private set; } internal static void Apply(Harmony harmony) { Type type = AccessTools.TypeByName("SceneSkipper"); CachedSceneSkipper = (type, (type == null) ? null : AccessTools.Method(type, "SkipScene", (Type[])null, (Type[])null)); _ignoreInputField = ((type == null) ? null : AccessTools.Field(type, "ignoreInput")); _isSkippingField = ((type == null) ? null : AccessTools.Field(type, "_isSkipping")); _transitionDurationField = ((type == null) ? null : AccessTools.Field(type, "transitionDuration")); (string, string, string, string)[] patchDefs = PatchDefs; for (int i = 0; i < patchDefs.Length; i++) { var (typeName, methodName, prefix, postfix) = patchDefs[i]; Patch(harmony, typeName, methodName, prefix, postfix); } } private static void Patch(Harmony harmony, string typeName, string methodName, string? prefix, string? postfix) { //IL_007a: 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) Type type = AccessTools.TypeByName(typeName); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, methodName, (Type[])null, (Type[])null)); if (type == null || methodInfo == null) { Plugin.Logger.LogWarning((object)("Patch target not found: " + typeName + "." + methodName + "; skipping.")); } else { HarmonyMethod val = ((prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(AccessTools.Method(typeof(SkipIntroPatcher), prefix, (Type[])null, (Type[])null))); HarmonyMethod val2 = ((postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(AccessTools.Method(typeof(SkipIntroPatcher), postfix, (Type[])null, (Type[])null))); harmony.Patch((MethodBase)methodInfo, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Logger.LogInfo((object)("Patched " + typeName + "." + methodName + ".")); } } private static bool OfflineSplashCoinFlipAwakePrefix() { return !Plugin.IsActive; } private static bool SceneSkipperStartPrefix(object __instance) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.IsActive) { return true; } if (Plugin.IsNetworkSetupScene(SceneManager.GetActiveScene())) { Plugin.Instance.Finish("Network setup SceneSkipper reached; game auth flow is now running"); return true; } PrepareSceneSkipper(__instance); Plugin.QueueSkipFromPatch("SceneSkipper.Start"); return false; } private static void SceneSkipperOnSceneLoadedPostfix(Scene scene) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (Plugin.IsActive) { if (Plugin.IsNetworkSetupScene(scene)) { Plugin.Instance.Finish("Network setup reached via SceneSkipper.OnSceneLoaded"); } else if (Plugin.IsMainMenuScene(scene)) { Plugin.Instance.Finish("Main menu reached via SceneSkipper.OnSceneLoaded"); } else { Plugin.QueueSkipFromPatch("SceneSkipper.OnSceneLoaded"); } } } private static bool SceneSkipperRoutinePrefix(object __instance, ref IEnumerator __result) { if (!Plugin.IsActive) { return true; } __result = ImmediateSkipRoutine(__instance); return false; } [IteratorStateMachine(typeof(d__14))] private static IEnumerator ImmediateSkipRoutine(object skipper) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__14(0) { skipper = skipper }; } internal static void PrepareSceneSkipper(object skipper) { _ignoreInputField?.SetValue(skipper, false); _isSkippingField?.SetValue(skipper, false); _transitionDurationField?.SetValue(skipper, 0f); } } internal static class StartupWindowFocus { private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); private const int SwShow = 5; private const int SwRestore = 9; [DllImport("user32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] private static extern bool BringWindowToTop(IntPtr hWnd); [DllImport("user32.dll")] private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll")] private static extern bool IsIconic(IntPtr hWnd); [DllImport("user32.dll")] private static extern IntPtr SetActiveWindow(IntPtr hWnd); [DllImport("user32.dll")] private static extern IntPtr SetFocus(IntPtr hWnd); [DllImport("user32.dll")] private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); [DllImport("user32.dll")] private static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll")] private static extern IntPtr GetShellWindow(); [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int processId); internal static bool TryBringCurrentProcessToFront() { //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_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 RuntimePlatform platform = Application.platform; if (((int)platform != 2 && (int)platform != 7) || 1 == 0) { return false; } try { IntPtr intPtr = FindCurrentProcessWindow(); if (intPtr == IntPtr.Zero) { return false; } ShowWindow(intPtr, IsIconic(intPtr) ? 9 : 5); BringWindowToTop(intPtr); SetActiveWindow(intPtr); SetFocus(intPtr); return SetForegroundWindow(intPtr); } catch (Exception ex) { Plugin.Logger.LogDebug((object)("Startup window focus failed: " + ex.GetType().Name + ": " + ex.Message)); return false; } } private static IntPtr FindCurrentProcessWindow() { using Process process = Process.GetCurrentProcess(); process.Refresh(); if (process.MainWindowHandle != IntPtr.Zero) { return process.MainWindowHandle; } int processId = process.Id; IntPtr shellWindow = GetShellWindow(); IntPtr result = IntPtr.Zero; EnumWindows(delegate(IntPtr window, IntPtr _) { if (window == shellWindow || !IsWindowVisible(window)) { return true; } GetWindowThreadProcessId(window, out var processId2); if (processId2 != processId) { return true; } result = window; return false; }, IntPtr.Zero); return result; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "Skip_Intro"; public const string PLUGIN_NAME = "Skip loading intro for GWYF"; public const string PLUGIN_VERSION = "1.0.0"; } }