using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MMTools; using Microsoft.CodeAnalysis; using MonoMod.Utils; using Shared; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyCompany("p1xel8ted")] [assembly: AssemblyConfiguration("Release-Thunderstore")] [assembly: AssemblyDescription("SkipOfTheLamb")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+3a81a0a58816704b0931fe3f4150b15f08deed1a")] [assembly: AssemblyProduct("SkipOfTheLamb")] [assembly: AssemblyTitle("SkipOfTheLamb")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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 SkipOfTheLamb { [Harmony] public static class Patches { private static bool _hasSkippedDevIntros; [HarmonyPrefix] [HarmonyPatch(typeof(IntroDeathSceneManager), "GiveCrown")] public static bool IntroDeathSceneManager_GiveCrown(ref IntroDeathSceneManager __instance) { if (!Plugin.SkipCrownVideo.Value) { return true; } __instance.VideoComplete(); DataManager.Instance.HadInitialDeathCatConversation = true; return false; } [HarmonyPrefix] [HarmonyPatch(typeof(LoadMainMenu), "Start")] public static bool LoadMainMenu_Start() { if (_hasSkippedDevIntros || !Plugin.SkipDevIntros.Value) { return true; } _hasSkippedDevIntros = true; ((Behaviour)AudioManager.Instance).enabled = true; MMTransition.Play((TransitionType)0, (Effect)0, "Main Menu", 0f, "", (Action)null, (Action)null); return false; } } [BepInPlugin("p1xel8ted.cotl.skipofthelamb", "Skip of the Lamb", "0.1.0")] public class Plugin : BaseUnityPlugin { private const string PluginGuid = "p1xel8ted.cotl.skipofthelamb"; private const string PluginName = "Skip of the Lamb"; private const string PluginVer = "0.1.0"; private const string CultOfQoLGuid = "p1xel8ted.cotl.CultOfQoLCollection"; internal static ManualLogSource Log { get; private set; } internal static ConfigEntry SkipDevIntros { get; private set; } internal static ConfigEntry SkipCrownVideo { get; private set; } private void Awake() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; SkipDevIntros = ((BaseUnityPlugin)this).Config.Bind("General", "Skip Intros", false, new ConfigDescription("Skip splash screens.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); SkipCrownVideo = ((BaseUnityPlugin)this).Config.Bind("General", "Skip Crown Video", false, new ConfigDescription("Skips the video when the lamb gets given the crown.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "p1xel8ted.cotl.skipofthelamb"); if (Chainloader.PluginInfos.ContainsKey("p1xel8ted.cotl.CultOfQoLCollection")) { Log.LogWarning((object)"CultOfQoL detected. Its skip intro/video features will be disabled in favour of Skip of the Lamb."); } Helpers.PrintModLoaded("Skip of the Lamb", ((BaseUnityPlugin)this).Logger); } } } namespace Shared { public static class Helpers { private static class StorefrontDetector { private static readonly string[] PiracyFiles = new string[42] { "SmartSteamEmu.ini", "codex.ini", "steam_emu.ini", "goldberg_emulator.dll", "3dmgame.dll", "ALI213.dll", "crack", "crack.exe", "steam_api64_o.dll", "steamclient_loader.dll", "CODEX", "Goldberg", "REVOLT", "SKIDROW", "PROPHET", "CPY", "PLAZA", "FLT", "FLT.dll", "HOODLUM", "EMPRESS", "VALVEEMPRESS", "DARKSiDERS", "RAZOR1911", "TENOKE", "DOGE", "BAT", "P2P", "nosTEAM", "FCKDRM", "unarc.dll", "uninstall.exe", "setup.exe", "INSTALLER", "steam_api64.cdx.dll", "Launcher.exe", "Redist", "RLD!", "fix.exe", "crackfix", "ReadMe.txt", "README.nfo" }; public static string DetectStorefront() { string dir = Directory.GetCurrentDirectory(); string text = "Unknown"; if (File.Exists(Path.Combine(dir, "steam_api.dll")) || File.Exists(Path.Combine(dir, "steam_api64.dll")) || File.Exists(Path.Combine(dir, "steam_appid.txt")) || Directory.Exists(Path.Combine(dir, "steam_settings"))) { text = "Steam"; } else if (Directory.GetFiles(dir, "goggame-*.info").Any() || File.Exists(Path.Combine(dir, "galaxy.dll"))) { text = "GOG"; } else if (File.Exists(Path.Combine(dir, "EOSSDK-Win64-Shipping.dll")) || File.Exists(Path.Combine(dir, "EpicOnlineServices.dll")) || Directory.Exists(Path.Combine(dir, ".egstore"))) { text = "Epic"; } else if (IsProcessRunning("steam")) { text = "Steam (process only)"; } else if (IsProcessRunning("GalaxyClient")) { text = "GOG (process only)"; } else if (IsProcessRunning("EpicGamesLauncher")) { text = "Epic (process only)"; } if (PiracyFiles.Any((string pirate) => File.Exists(Path.Combine(dir, pirate)) || Directory.Exists(Path.Combine(dir, pirate)))) { text += " + Possible Pirated/Cracked Files Found!"; } return text; } private static bool IsProcessRunning(string name) { return Process.GetProcessesByName(name).Length != 0; } } [CompilerGenerated] private sealed class d__17 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public IEnumerator original; public Type[] typesToRemove; 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() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } while (original.MoveNext()) { object current = original.Current; if (current != null && !ArrayExtensions.Contains(typesToRemove, current.GetType())) { <>2__current = current; <>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(); } } internal static List AllFollowers => FollowerManager.Followers.SelectMany((KeyValuePair> followerList) => followerList.Value).ToList(); public static void PrintModLoaded(string plugin, ManualLogSource logger) { //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_0089: Unknown result type (might be due to invalid IL or missing references) string text = Application.version.Replace("\r", "").Replace("\n", ""); string buildGUID = Application.buildGUID; Platform current = PlatformHelper.Current; string text2 = StorefrontDetector.DetectStorefront(); logger.LogInfo((object)"=========================================="); logger.LogInfo((object)(" Plugin Loaded: " + plugin)); logger.LogInfo((object)(" Version : " + text + " (BuildGUID: " + buildGUID + ")")); logger.LogInfo((object)$" Platform : {current}"); logger.LogInfo((object)(" Storefront: " + text2)); logger.LogInfo((object)"=========================================="); } private static FollowerTask_ClearRubble GetRubbleTask() { SortedList sortedList = new SortedList(); foreach (Structures_Rubble item in StructureManager.GetAllStructuresOfType()) { item.GetAvailableTasks((ScheduledActivity)0, sortedList); } FollowerTask? obj = sortedList.Values.FirstOrDefault(); return (FollowerTask_ClearRubble)(object)((obj is FollowerTask_ClearRubble) ? obj : null); } private static FollowerTask_Janitor GetJanitorTask() { SortedList sortedList = new SortedList(); foreach (Structures_JanitorStation item in StructureManager.GetAllStructuresOfType()) { item.GetAvailableTasks((ScheduledActivity)0, sortedList); } FollowerTask? obj = sortedList.Values.FirstOrDefault(); return (FollowerTask_Janitor)(object)((obj is FollowerTask_Janitor) ? obj : null); } private static FollowerTask_Refinery GetRefineryTask() { SortedList sortedList = new SortedList(); foreach (Structures_Refinery item in StructureManager.GetAllStructuresOfType()) { item.GetAvailableTasks((ScheduledActivity)0, sortedList); } FollowerTask? obj = sortedList.Values.FirstOrDefault(); return (FollowerTask_Refinery)(object)((obj is FollowerTask_Refinery) ? obj : null); } private static FollowerTask_Undertaker GetMorgueTask() { SortedList sortedList = new SortedList(); foreach (Structures_Morgue item in StructureManager.GetAllStructuresOfType()) { item.GetAvailableTasks((ScheduledActivity)0, sortedList); } FollowerTask? obj = sortedList.Values.FirstOrDefault(); return (FollowerTask_Undertaker)(object)((obj is FollowerTask_Undertaker) ? obj : null); } private static void StartTask(FollowerBrain brain, FollowerTask task) { brain.CompleteCurrentTask(); brain.HardSwapToTask(task); } private static void StartTaskFromCommand(FollowerBrain brain, FollowerCommands command) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Expected I4, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_0235: Unknown result type (might be due to invalid IL or missing references) switch ((int)command) { case 14: StartTask(brain, (FollowerTask)new FollowerTask_ChopTrees()); break; case 17: StartTask(brain, (FollowerTask)(object)GetRubbleTask()); break; case 27: StartTask(brain, (FollowerTask)(object)GetPrayTask()); break; case 47: StartTask(brain, (FollowerTask)(object)GetFarmTask()); break; case 28: StartTask(brain, (FollowerTask)(object)GetBuildTask()); break; case 30: StartTask(brain, (FollowerTask)(object)GetKitchenTask()); break; case 58: StartTask(brain, (FollowerTask)(object)GetJanitorTask()); break; case 64: StartTask(brain, (FollowerTask)(object)GetRefineryTask()); break; case 81: StartTask(brain, (FollowerTask)(object)GetMorgueTask()); break; case 88: StartTask(brain, (FollowerTask)(object)GetBrewTask()); break; default: StartTask(brain, GetRandomTask(brain)); throw new ArgumentOutOfRangeException("command", command, null); case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 15: case 16: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 29: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 59: case 60: case 61: case 62: case 63: case 65: case 66: case 67: case 68: case 69: case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 78: case 79: case 80: case 82: case 83: case 84: case 85: case 86: case 87: case 89: case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 97: case 98: case 99: case 100: case 101: case 102: case 103: case 104: break; } } private static FollowerTask_Cook GetKitchenTask() { SortedList sortedList = new SortedList(); foreach (Structures_Kitchen item in StructureManager.GetAllStructuresOfType()) { ((Structures_CookingFire)item).GetAvailableTasks((ScheduledActivity)0, sortedList); } FollowerTask? obj = sortedList.Values.FirstOrDefault(); return (FollowerTask_Cook)(object)((obj is FollowerTask_Cook) ? obj : null); } private static FollowerTask GetRandomTask(FollowerBrain brain) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return FollowerBrain.GetDesiredTask_Work(brain.Location).FirstOrDefault(); } private static FollowerTask_Brew GetBrewTask() { SortedList sortedList = new SortedList(); foreach (Structures_Pub item in StructureManager.GetAllStructuresOfType()) { item.GetAvailableTasks((ScheduledActivity)0, sortedList); } FollowerTask? obj = sortedList.Values.FirstOrDefault(); return (FollowerTask_Brew)(object)((obj is FollowerTask_Brew) ? obj : null); } private static FollowerTask_Farm GetFarmTask() { SortedList sortedList = new SortedList(); foreach (Structures_FarmerStation item in StructureManager.GetAllStructuresOfType()) { item.GetAvailableTasks((ScheduledActivity)0, sortedList); } FollowerTask? obj = sortedList.Values.FirstOrDefault(); return (FollowerTask_Farm)(object)((obj is FollowerTask_Farm) ? obj : null); } public static bool IsMultiplierActive(float value) { return !Mathf.Approximately(value, 1f); } private static FollowerTask_Pray GetPrayTask() { SortedList sortedList = new SortedList(); foreach (Structures_Shrine item in StructureManager.GetAllStructuresOfType()) { item.GetAvailableTasks((ScheduledActivity)0, sortedList); } FollowerTask? obj = sortedList.Values.FirstOrDefault(); return (FollowerTask_Pray)(object)((obj is FollowerTask_Pray) ? obj : null); } private static FollowerTask_Build GetBuildTask() { SortedList sortedList = new SortedList(); foreach (Structures_BuildSite item in StructureManager.GetAllStructuresOfType()) { item.GetAvailableTasks((ScheduledActivity)0, sortedList); } FollowerTask? obj = sortedList.Values.FirstOrDefault(); return (FollowerTask_Build)(object)((obj is FollowerTask_Build) ? obj : null); } [IteratorStateMachine(typeof(d__17))] public static IEnumerator FilterEnumerator(IEnumerator original, Type[] typesToRemove) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__17(0) { original = original, typesToRemove = typesToRemove }; } } internal sealed class ConfigurationManagerAttributes { public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput); public bool? ShowRangeAsPercent; public Action CustomDrawer; public CustomHotkeyDrawerFunc CustomHotkeyDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public Func ObjToStr; public Func StrToObj; } }