Decompiled source of HallwaySkip v0.1.0

CutsceneSkip.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dialogue;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NineSolsAPI;
using TMPro;
using UnityEngine;
using UnityEngine.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("CutsceneSkip")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A Nine Sols mod that enables skipping any cutscene or dialogue (that won't break the game).")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9d52dfec2871d129ba0320f0a08d5925bb401877")]
[assembly: AssemblyProduct("CutsceneSkip")]
[assembly: AssemblyTitle("CutsceneSkip")]
[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 CutsceneSkip
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("CutsceneSkip", "CutsceneSkip", "1.0.0")]
	public class CutsceneSkip : BaseUnityPlugin
	{
		private static ConfigEntry<KeyboardShortcut> skipKeybind = null;

		private Harmony harmony;

		public static (A2_SG4_Logic?, string) activeA2SG4 = (null, "");

		public static (A4_S5_Logic?, string) activeA4S5 = (null, "");

		public static string dialogueSkipNotificationId = "";

		public static (SimpleCutsceneManager?, string) activeCutscene = (null, "");

		public static (VideoPlayAction?, string) activeVideo = (null, "");

		public static string SkipKeybindText()
		{
			//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)
			KeyboardShortcut value = skipKeybind.Value;
			return ((KeyboardShortcut)(ref value)).Serialize();
		}

		private void Awake()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Log.Init(((BaseUnityPlugin)this).Logger);
			RCGLifeCycle.DontDestroyForever(((Component)this).gameObject);
			harmony = Harmony.CreateAndPatchAll(typeof(CutsceneSkip).Assembly, (string)null);
			skipKeybind = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("", "Skip Keybind", new KeyboardShortcut((KeyCode)107, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "The keyboard shortcut to actually skip cutscenes and dialogue.");
			KeybindManager.Add((MonoBehaviour)(object)this, (Action)SkipActiveCutsceneOrDialogue, (Func<KeyboardShortcut>)(() => skipKeybind.Value));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin CutsceneSkip is loaded!");
			Notifications.Awake();
		}

		private void SkipActiveCutsceneOrDialogue()
		{
			if ((Object)(object)activeA2SG4.Item1 != (Object)null)
			{
				A2_SG4_Logic? item = activeA2SG4.Item1;
				Log.Info("Found A2_SG4_Logic a.k.a. Heng Power Reservoir flashback, calling A2_SG4_Logic.TrySkip() as a special case");
				item.TrySkip();
				Notifications.CancelNotification(activeA2SG4.Item2);
				return;
			}
			if ((Object)(object)activeA4S5.Item1 != (Object)null)
			{
				A4_S5_Logic item2 = activeA4S5.Item1;
				if (item2.BossKilled.CurrentValue)
				{
					Log.Info("Found A4_S5_Logic a.k.a. Sky Rending Claw fight. Claw already killed. Applying special case logic to skip post-fight scene.");
					item2.FinishCutscene.TrySkip();
				}
				else
				{
					if (((Component)item2.GianMechClawMonsterBase).gameObject.activeSelf)
					{
						Log.Info("Found A4_S5_Logic a.k.a. Sky Rending Claw fight. Claw not yet killed. But claw is already active, so trying to skip this now would just softlock. Doing nothing.");
						return;
					}
					Log.Info("Found A4_S5_Logic a.k.a. Sky Rending Claw fight. Claw not yet killed. Applying special case logic to skip pre-fight scenes.");
					GameObject.Find("A4_S5/A4_S5_Logic(DisableMeForBossDesign)/CUTSCENE_START/MangaView_OriginalPrefab/MANGACanvas").SetActive(false);
					item2.BeforeMangaBubble.TrySkip();
					item2.BubbleDialogue.TrySkip();
					item2.TrySkip();
				}
				Notifications.CancelNotification(activeA4S5.Item2);
				return;
			}
			GameObject obj = GameObject.Find("GameCore(Clone)/RCG LifeCycle/UIManager/GameplayUICamera/Always Canvas/DialoguePlayer(KeepThisEnable)");
			DialoguePlayer val = ((obj != null) ? obj.GetComponent<DialoguePlayer>() : null);
			if ((Object)(object)val != (Object)null && (Object)(object)AccessTools.FieldRefAccess<DialoguePlayer, DialogueGraph>("playingDialogueGraph").Invoke(val) != (Object)null)
			{
				Log.Info("calling DialoguePlayer.playingDialogueGraph.TrySkip()");
				val.TrySkip();
				if (dialogueSkipNotificationId != "")
				{
					Notifications.CancelNotification(dialogueSkipNotificationId);
					dialogueSkipNotificationId = "";
				}
			}
			else if ((Object)(object)activeCutscene.Item1 != (Object)null)
			{
				SimpleCutsceneManager item3 = activeCutscene.Item1;
				Log.Info("calling TrySkip() on " + ((Object)item3).name);
				AccessTools.Method(typeof(SimpleCutsceneManager), "TrySkip", (Type[])null, (Type[])null).Invoke(item3, Array.Empty<object>());
				if (AccessTools.FieldRefAccess<SimpleCutsceneManager, bool>("isMangaPauseing").Invoke(item3))
				{
					Log.Info("also calling Resume() since it was 'manga paused'");
					AccessTools.Method(typeof(SimpleCutsceneManager), "Resume", (Type[])null, (Type[])null).Invoke(item3, Array.Empty<object>());
				}
				Notifications.CancelNotification(activeCutscene.Item2);
				activeCutscene = (null, "");
			}
			else if ((Object)(object)activeVideo.Item1 != (Object)null)
			{
				VideoPlayAction item4 = activeVideo.Item1;
				Log.Info("calling TrySkip() on " + ((Object)item4).name);
				AccessTools.Method(typeof(VideoPlayAction), "TrySkip", (Type[])null, (Type[])null).Invoke(item4, Array.Empty<object>());
				Notifications.CancelNotification(activeVideo.Item2);
				activeVideo = (null, "");
			}
		}

		private void Update()
		{
			Notifications.Update();
		}

		private void OnDestroy()
		{
			harmony.UnpatchSelf();
			Notifications.OnDestroy();
		}
	}
	internal static class Log
	{
		private static ManualLogSource? logSource;

		internal static void Init(ManualLogSource logSource)
		{
			Log.logSource = logSource;
		}

		internal static void Debug(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogDebug(data);
			}
		}

		internal static void Error(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogError(data);
			}
		}

		internal static void Fatal(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogFatal(data);
			}
		}

		internal static void Info(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogInfo(data);
			}
		}

		internal static void Message(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogMessage(data);
			}
		}

		internal static void Warning(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogWarning(data);
			}
		}
	}
	internal class Notifications
	{
		private struct Notification
		{
			public string id;

			public DateTimeOffset timestamp;

			public string displayText;
		}

		private static Canvas CanvasComponent = null;

		private static TextMeshProUGUI TextComponent = null;

		private static bool isDirty = false;

		private static List<Notification> notificationStack = new List<Notification>();

		private static readonly TimeSpan expiry = TimeSpan.FromSeconds(10.0);

		public static void Awake()
		{
			//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_0010: Expected O, but got Unknown
			//IL_0010: 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)
			GameObject val = new GameObject("NineSolsAPI-FullscreenCanvas");
			RCGLifeCycle.DontDestroyForever(val);
			CanvasComponent = val.AddComponent<Canvas>();
			CanvasComponent.renderMode = (RenderMode)0;
			TextComponent = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)TextComponent).alignment = (TextAlignmentOptions)1028;
			((TMP_Text)TextComponent).fontSize = 20f;
			((Graphic)TextComponent).color = Color.white;
		}

		public static void Update()
		{
			UpdateText();
		}

		public static void OnDestroy()
		{
			Object.Destroy((Object)(object)((Component)CanvasComponent).gameObject);
		}

		public static void UpdateText()
		{
			DateTimeOffset now = DateTimeOffset.UtcNow;
			int num = notificationStack.RemoveAll((Notification notification) => now - notification.timestamp > expiry);
			isDirty |= num > 0;
			if (isDirty)
			{
				((TMP_Text)TextComponent).text = string.Join('\n', notificationStack.Select((Notification n) => n.displayText));
				isDirty = false;
			}
		}

		public static string AddNotification(string displayText)
		{
			Log.Info("Notifications.AddNotification(" + displayText + ")");
			string text = Guid.NewGuid().ToString("N");
			notificationStack.Add(new Notification
			{
				id = text,
				timestamp = DateTimeOffset.UtcNow,
				displayText = displayText
			});
			isDirty = true;
			return text;
		}

		public static void CancelNotification(string id)
		{
			string id2 = id;
			Log.Info("Notifications.CancelNotification(" + id2 + ")");
			if (id2 != null && id2 != "")
			{
				int num = notificationStack.RemoveAll((Notification x) => x.id == id2);
				isDirty |= num > 0;
			}
		}
	}
	[HarmonyPatch]
	public class Patches
	{
		private static List<string> skipDenylist = new List<string>
		{
			"A1_S2_GameLevel/Room/Prefab/Gameplay2_Alina/Simple Binding Tool/SimpleCutSceneFSM_關門戰開頭演出/FSM Animator/LogicRoot/[CutScene]", "A2_S1/Room/Prefab/EnterPyramid_Acting/[CutScene]ActivePyramidAndEnter", "A3_S1/Room/Prefab/妹妹回憶_SimpleCutSceneFSM Variant/FSM Animator/LogicRoot/[CutScene]", "A4_S4/ZGunAndDoor/Shield Giant Bot Control Provider Variant_Cutscene/Hack Control Monster FSM/FSM Animator/LogicRoot/Cutscene/LogicRoot/[CutScene]", "A5_S5/Room/SimpleCutSceneFSM_JieChuan and Jee/FSM Animator/LogicRoot/[CutScene]", "AG_S2/Room/NPCs/議會演出相關Binding/ShanShan 軒軒分身 FSM/FSM Animator/CutScene/[CutScene] 食譜_團圓飯/FSM Animator/LogicRoot/[CutScene]", "GameLevel/Room/Prefab/EventBinder/General Boss Fight FSM Object Variant/FSM Animator/[CutScene] 易公死亡", "A3_S5_BossGouMang_GameLevel/Room/Simple Binding Tool/BossGouMangLogic/[CutScene]/[CutScene]Goumang_Explosion_Drop/[Timeline]Goumang_Explosion_Drop", "A5_S2/Room/SimpleCutSceneFSM_A5妹妹回憶/FSM Animator/LogicRoot/[CutScene]", "A4_S3/Room/Prefab/CutScene_ChangeScene_FSM Variant/FSM Animator/LogicRoot/[CutScene]EnterScene",
			"A11_S2/CutScene_ChangeScene_FSM Variant/FSM Animator/LogicRoot/[CutScene]EnterScene", "AG_GoHome/Room/Prefab/SimpleCutSceneFSM_搭公車/FSM Animator/LogicRoot/[CutScene]", "A1_S1_GameLevel/Room/A1_S1_Tutorial_Logic/[CutScene]AfterTutorial_AI_Call/[Timeline]", "A4_S3/Room/Prefab/ElementRoom/ElementDoor FSM/ElementDoor FSM/FSM Animator/LogicRoot/[CutScene]Eenter_A4SG4", "A2_S5_ BossHorseman_GameLevel/Room/Simple Binding Tool/Boss_SpearHorse_Logic/[CutScene]SpearHorse_End", "A0_S6/Room/Prefab/SimpleCutSceneFSM_道長死亡/FSM Animator/LogicRoot/Cutscene_TaoChangPart2", "A4_S5/A4_S5_Logic(DisableMeForBossDesign)/CUTSCENE_START", "A4_S5/A4_S5_Logic(DisableMeForBossDesign)/CUTSENE_EMERGENCY", "A4_S5/A4_S5_Logic(DisableMeForBossDesign)/CUTSCENE_Finish", "A11_S2/Room/Prefab/EventBinder/OldBoy FSM Object/FSM Animator/LogicRoot/[CutScene]OldBoyFighting/[Timeline]"
		};

		private static HashSet<string> skippableVideos = new HashSet<string> { "GameLevel/Room/Prefab/SimpleCutSceneFSM_結局_大爆炸/--[States]/FSM/[State] PlayCutSceneEnd/[Action] VideoPlayAction", "A7_S6_Memory_Butterfly_CutScene_GameLevel/A7_S6_Cutscene FSM/--[States]/FSM/[State] PlayingVideo/[Action] VideoPlayAction" };

		public static string GetFullPath(GameObject go)
		{
			Transform val = go.transform;
			List<string> list = new List<string>();
			while ((Object)(object)val != (Object)null)
			{
				list.Add(((Object)val).name);
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SimpleCutsceneManager), "PlayAnimation")]
		private static void SimpleCutsceneManager_PlayAnimation(SimpleCutsceneManager __instance)
		{
			string fullPath = GetFullPath(((Component)__instance).gameObject);
			Log.Debug("SimpleCutsceneManager_PlayAnimation " + fullPath);
			if (skipDenylist.Contains(fullPath))
			{
				Log.Info("not allowing skip for cutscene " + fullPath + " because it's on the skip denylist");
				return;
			}
			if (((Object)__instance).name.EndsWith("[TimeLine]CrateEnter_L") || ((Object)__instance).name.EndsWith("[TimeLine]CrateEnter_R"))
			{
				Log.Info("not allowing skip for " + fullPath + " because all crate exit 'cutscenes' I've tested instantly softlock when skipped");
				return;
			}
			if (((Object)__instance).name == "[CutScene]調閱報告")
			{
				Log.Info("not allowing skip for " + fullPath + " because all \"[CutScene]調閱報告\" / Eigong lab report cutscenes risk softlocking when skipped");
				return;
			}
			string item = "";
			if (((Object)__instance).name.EndsWith("_EnterScene"))
			{
				Log.Info("skipping notification for " + ((Object)__instance).name + " because transition 'cutscenes' are typically over before the player can even see the toast");
			}
			else
			{
				item = Notifications.AddNotification("Press " + CutsceneSkip.SkipKeybindText() + " to Skip This Cutscene");
			}
			CutsceneSkip.activeCutscene = (__instance, item);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SimpleCutsceneManager), "End")]
		private static void SimpleCutsceneManager_End(SimpleCutsceneManager __instance)
		{
			Log.Debug("SimpleCutsceneManager_End " + ((Object)__instance).name);
			if ((Object)(object)CutsceneSkip.activeCutscene.Item1 == (Object)(object)__instance)
			{
				CutsceneSkip.activeCutscene = (null, "");
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(DialoguePlayer), "StartDialogue")]
		private static void DialoguePlayer_StartDialogue(DialoguePlayer __instance)
		{
			Log.Debug("DialoguePlayer_StartDialogue " + ((Object)__instance).name);
			CutsceneSkip.dialogueSkipNotificationId = Notifications.AddNotification("Press " + CutsceneSkip.SkipKeybindText() + " to Skip This Dialogue");
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(VideoPlayAction), "OnStateEnterImplement")]
		private static void VideoPlayAction_OnStateEnterImplement(VideoPlayAction __instance)
		{
			string fullPath = GetFullPath(((Component)__instance).gameObject);
			Log.Debug("VideoPlayAction_OnStateEnterImplement " + fullPath);
			if (skippableVideos.Contains(fullPath))
			{
				string item = Notifications.AddNotification("Press " + CutsceneSkip.SkipKeybindText() + " to Skip This Video");
				CutsceneSkip.activeVideo = (__instance, item);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(VideoPlayAction), "VideoClipDone")]
		private static void VideoPlayAction_VideoClipDone(VideoPlayAction __instance)
		{
			Log.Debug("VideoPlayAction_VideoClipDone " + ((Object)__instance).name);
			if ((Object)(object)CutsceneSkip.activeVideo.Item1 == (Object)(object)__instance)
			{
				CutsceneSkip.activeVideo = (null, "");
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(A2_SG4_Logic), "EnterLevelStart")]
		private static void A2_SG4_Logic_EnterLevelStart(A2_SG4_Logic __instance)
		{
			Log.Info("A2_SG4_Logic_EnterLevelStart / Heng Power Reservoir flashback");
			string item = Notifications.AddNotification("Press " + CutsceneSkip.SkipKeybindText() + " to Skip This Heng Flashback");
			CutsceneSkip.activeA2SG4 = (__instance, item);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(A4_S5_Logic), "EnterLevelStart")]
		private static void A4_S5_Logic_EnterLevelStart(A4_S5_Logic __instance)
		{
			Log.Info("A4_S5_Logic_EnterLevelStart / Sky Rending Claw Pre-Fight Scenes");
			string item = Notifications.AddNotification("Press " + CutsceneSkip.SkipKeybindText() + " to Skip Pre-Claw Fight Cutscenes");
			CutsceneSkip.activeA4S5 = (__instance, item);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(A4_S5_Logic), "FooGameComplete")]
		private static void A4_S5_Logic_FooGameComplete(A4_S5_Logic __instance)
		{
			Log.Info("A4_S5_Logic_FooGameComplete / Sky Rending Claw Post-Fight Scenes");
			if ((Object)(object)CutsceneSkip.activeA4S5.Item1 != (Object)null)
			{
				Notifications.CancelNotification(CutsceneSkip.activeA4S5.Item2);
			}
			string item = Notifications.AddNotification("Press " + CutsceneSkip.SkipKeybindText() + " to Skip Post-Claw Fight Cutscene");
			CutsceneSkip.activeA4S5 = (__instance, item);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "CutsceneSkip";

		public const string PLUGIN_NAME = "CutsceneSkip";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

HallwaySkip.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NineSolsAPI;
using TMPro;
using UnityEngine;
using UnityEngine.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("HallwaySkip")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A Nine Sols mod that lets you skip the long hallway fight sequence after the Point of no Return")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a1506f77850caa8932b042eac16bf86055121cb3")]
[assembly: AssemblyProduct("HallwaySkip")]
[assembly: AssemblyTitle("HallwaySkip")]
[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 HallwaySkip
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("HallwaySkip", "HallwaySkip", "1.0.0")]
	public class HallwaySkip : BaseUnityPlugin
	{
		private static ConfigEntry<KeyboardShortcut> skipKeybind;

		private Harmony harmony;

		public static SimpleCutsceneManager activeHallwayCutscene;

		public static string SkipKeybindText()
		{
			//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)
			KeyboardShortcut value = skipKeybind.Value;
			return ((KeyboardShortcut)(ref value)).Serialize();
		}

		private void Awake()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Log.Init(((BaseUnityPlugin)this).Logger);
			RCGLifeCycle.DontDestroyForever(((Component)this).gameObject);
			harmony = Harmony.CreateAndPatchAll(typeof(HallwaySkip).Assembly, (string)null);
			skipKeybind = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("", "Skip Keybind", new KeyboardShortcut((KeyCode)107, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "The keyboard shortcut to actually skip the hallway.");
			KeybindManager.Add((MonoBehaviour)(object)this, (Action)SkipHallwayCutscene, (Func<KeyboardShortcut>)(() => skipKeybind.Value));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin HallwaySkip is loaded!");
			TextDisplay.Awake();
		}

		private void SkipHallwayCutscene()
		{
			if ((Object)(object)activeHallwayCutscene != (Object)null)
			{
				Log.Info("calling TrySkip() on " + ((Object)activeHallwayCutscene).name);
				AccessTools.Method(typeof(SimpleCutsceneManager), "TrySkip", (Type[])null, (Type[])null).Invoke(activeHallwayCutscene, Array.Empty<object>());
				activeHallwayCutscene = null;
				((TMP_Text)TextDisplay.TextComponent).text = null;
			}
		}

		private void OnDestroy()
		{
			harmony.UnpatchSelf();
			TextDisplay.OnDestroy();
		}
	}
	internal static class Log
	{
		private static ManualLogSource? logSource;

		internal static void Init(ManualLogSource logSource)
		{
			Log.logSource = logSource;
		}

		internal static void Debug(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogDebug(data);
			}
		}

		internal static void Error(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogError(data);
			}
		}

		internal static void Fatal(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogFatal(data);
			}
		}

		internal static void Info(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogInfo(data);
			}
		}

		internal static void Message(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogMessage(data);
			}
		}

		internal static void Warning(object data)
		{
			ManualLogSource? obj = logSource;
			if (obj != null)
			{
				obj.LogWarning(data);
			}
		}
	}
	[HarmonyPatch]
	public class Patches
	{
		private static string hallwayCutsceneGOPath = "A11_S2/Room/Prefab/EventBinder/OldBoy FSM Object/FSM Animator/LogicRoot/[CutScene]OldBoyFighting/[Timeline]";

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SimpleCutsceneManager), "PlayAnimation")]
		private static void SimpleCutsceneManager_PlayAnimation(SimpleCutsceneManager __instance)
		{
			GameObject val = GameObject.Find(hallwayCutsceneGOPath);
			if ((Object)(object)val != (Object)null && (Object)(object)val == (Object)(object)((Component)__instance).gameObject)
			{
				HallwaySkip.activeHallwayCutscene = __instance;
				((TMP_Text)TextDisplay.TextComponent).text = "Press " + HallwaySkip.SkipKeybindText() + " to Skip The Hallway Fight";
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SimpleCutsceneManager), "End")]
		private static void SimpleCutsceneManager_End(SimpleCutsceneManager __instance)
		{
			Log.Debug("SimpleCutsceneManager_End " + ((Object)__instance).name);
			if ((Object)(object)HallwaySkip.activeHallwayCutscene == (Object)(object)__instance)
			{
				HallwaySkip.activeHallwayCutscene = null;
				((TMP_Text)TextDisplay.TextComponent).text = null;
			}
		}
	}
	internal class TextDisplay
	{
		private static Canvas CanvasComponent;

		public static TextMeshProUGUI TextComponent;

		public static void Awake()
		{
			//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_0010: Expected O, but got Unknown
			//IL_0010: 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)
			GameObject val = new GameObject("NineSolsAPI-FullscreenCanvas");
			RCGLifeCycle.DontDestroyForever(val);
			CanvasComponent = val.AddComponent<Canvas>();
			CanvasComponent.renderMode = (RenderMode)0;
			TextComponent = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)TextComponent).alignment = (TextAlignmentOptions)1028;
			((TMP_Text)TextComponent).fontSize = 20f;
			((Graphic)TextComponent).color = Color.white;
		}

		public static void OnDestroy()
		{
			Object.Destroy((Object)(object)((Component)CanvasComponent).gameObject);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "HallwaySkip";

		public const string PLUGIN_NAME = "HallwaySkip";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}