Decompiled source of FastStartup v0.2.0

FastStartup.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 Microsoft.CodeAnalysis;
using On;
using REPOLib;
using UnityEngine;

[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("FastStartup")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ebfef4e9507f27d1811b694c3194d362c95466be")]
[assembly: AssemblyProduct("FastStartup")]
[assembly: AssemblyTitle("FastStartup")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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 FastStartup
{
	internal class Config
	{
		public readonly bool Multiplayer;

		public readonly SaveMode SaveMode;

		public readonly string SaveFileName;

		public readonly bool OverrideLevel;

		public readonly string LevelName;

		public Config(ConfigFile file)
		{
			Multiplayer = file.Bind<bool>("General", "Multiplayer", true, "Whether to start a multiplayer or singleplayer lobby").Value;
			SaveMode = file.Bind<SaveMode>("General", "SaveMode", SaveMode.ResetOnStartup, "ResetOnStartup: Create a new save and reset it on each startup.CreateOnStartup: Create a brand new save on each startup.Reuse: Use an existing save, without resetting.").Value;
			SaveFileName = file.Bind<string>("General", "SaveFileName", "REPO_FASTSTARTUP_SAVE", "The name of the save file to use.").Value;
			OverrideLevel = file.Bind<bool>("General", "OverrideLevel", false, "Whether to always start in the same level. Requires the LevelName option to be set.").Value;
			LevelName = file.Bind<string>("General", "LevelName", string.Empty, "The name of the level to start at. The 'Level - ' prefix is optional. Only applicable when OverrideLevel is true.").Value;
		}
	}
	internal static class Patches
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__SkipMainMenu;

			public static hook_CreateLobby <1>__CreateLobbyPatch;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_Awake <>9__0_0;

			public static hook_LevelAnimationStart <>9__0_1;

			public static hook_SetRunLevel <>9__0_2;

			internal void <Init>b__0_0(orig_Awake orig, RunManager self)
			{
				orig.Invoke(self);
				((MonoBehaviour)self).StartCoroutine(YieldThen(Plugin.SkipMainMenu));
			}

			internal void <Init>b__0_1(orig_LevelAnimationStart _, LoadingUI self)
			{
				self.levelAnimationStarted = true;
				self.levelAnimationCompleted = true;
			}

			internal void <Init>b__0_2(orig_SetRunLevel orig, RunManager self)
			{
				if (!Plugin.OverrideLevel())
				{
					orig.Invoke(self);
				}
			}
		}

		[CompilerGenerated]
		private sealed class <CreateLobbyPatch>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public orig_CreateLobby orig;

			public NetworkConnect self;

			private IEnumerator <enumerator>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CreateLobbyPatch>d__2(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<enumerator>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<enumerator>5__2 = orig.Invoke(self);
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<enumerator>5__2.MoveNext())
				{
					<>2__current = <enumerator>5__2.Current;
					<>1__state = 1;
					return true;
				}
				Plugin.Log.LogInfo((object)"Lobby creation finished!");
				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 <YieldThen>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Action action;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <YieldThen>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;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					action();
					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 void Init()
		{
			//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)
			//IL_0037: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			if (Chainloader.PluginInfos.ContainsKey("REPOLib"))
			{
				RepoLibCompat.Init();
			}
			else
			{
				object obj = <>c.<>9__0_0;
				if (obj == null)
				{
					hook_Awake val = delegate(orig_Awake orig, RunManager self)
					{
						orig.Invoke(self);
						((MonoBehaviour)self).StartCoroutine(YieldThen(Plugin.SkipMainMenu));
					};
					<>c.<>9__0_0 = val;
					obj = (object)val;
				}
				RunManager.Awake += (hook_Awake)obj;
			}
			object obj2 = <>c.<>9__0_1;
			if (obj2 == null)
			{
				hook_LevelAnimationStart val2 = delegate(orig_LevelAnimationStart _, LoadingUI self)
				{
					self.levelAnimationStarted = true;
					self.levelAnimationCompleted = true;
				};
				<>c.<>9__0_1 = val2;
				obj2 = (object)val2;
			}
			LoadingUI.LevelAnimationStart += (hook_LevelAnimationStart)obj2;
			object obj3 = <>c.<>9__0_2;
			if (obj3 == null)
			{
				hook_SetRunLevel val3 = delegate(orig_SetRunLevel orig, RunManager self)
				{
					if (!Plugin.OverrideLevel())
					{
						orig.Invoke(self);
					}
				};
				<>c.<>9__0_2 = val3;
				obj3 = (object)val3;
			}
			RunManager.SetRunLevel += (hook_SetRunLevel)obj3;
			object obj4 = <>O.<1>__CreateLobbyPatch;
			if (obj4 == null)
			{
				hook_CreateLobby val4 = CreateLobbyPatch;
				<>O.<1>__CreateLobbyPatch = val4;
				obj4 = (object)val4;
			}
			NetworkConnect.CreateLobby += (hook_CreateLobby)obj4;
		}

		[IteratorStateMachine(typeof(<YieldThen>d__1))]
		private static IEnumerator YieldThen(Action action)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <YieldThen>d__1(0)
			{
				action = action
			};
		}

		[IteratorStateMachine(typeof(<CreateLobbyPatch>d__2))]
		private static IEnumerator CreateLobbyPatch(orig_CreateLobby orig, NetworkConnect self)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CreateLobbyPatch>d__2(0)
			{
				orig = orig,
				self = self
			};
		}
	}
	[BepInPlugin("com.kesomannen.FastStartup", "FastStartup", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private static bool _overrideLevelTrigger;

		internal static ManualLogSource Log;

		private static Config _config;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			_config = new Config(((BaseUnityPlugin)this).Config);
			Patches.Init();
		}

		internal static void SkipMainMenu()
		{
			Log.LogInfo((object)"Skipping main menu.");
			RunManager.instance.ResetProgress();
			List<string> list = SemiFunc.SaveFileGetAll();
			if (_config.SaveMode == SaveMode.CreateOnStartup)
			{
				Log.LogDebug((object)"Creating new save file.");
				SemiFunc.SaveFileCreate();
			}
			else
			{
				bool flag = list.Contains(_config.SaveFileName);
				if (_config.SaveMode == SaveMode.ResetOnStartup)
				{
					if (flag)
					{
						Log.LogDebug((object)"Deleting existing save file.");
						SemiFunc.SaveFileDelete(_config.SaveFileName);
					}
					else
					{
						Log.LogDebug((object)"Creating new save file.");
					}
				}
				else if (!flag)
				{
					Log.LogWarning((object)("Could not find save file " + _config.SaveFileName + "! Creating new file..."));
				}
				StatsManager.instance.saveFileCurrent = _config.SaveFileName;
				StatsManager.instance.SaveGame(_config.SaveFileName);
				SemiFunc.SaveFileLoad(_config.SaveFileName);
			}
			if (_config.OverrideLevel)
			{
				_overrideLevelTrigger = true;
			}
			if (_config.Multiplayer)
			{
				Log.LogDebug((object)"Starting multiplayer game.");
				Object.Instantiate<GameObject>(SteamManager.instance.networkConnectPrefab);
			}
			else
			{
				Log.LogDebug((object)"Starting singleplayer game.");
			}
			Log.LogDebug((object)"Changing level.");
			RunManager.instance.ChangeLevel(true, false, (ChangeLevelType)1);
		}

		internal static bool OverrideLevel()
		{
			if (!_overrideLevelTrigger)
			{
				return false;
			}
			_overrideLevelTrigger = false;
			Level val = Utils.FindLevel(_config.LevelName);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)("Level " + _config.LevelName + " not found! Defaulting to random..."));
				return false;
			}
			Log.LogDebug((object)("Overriding level to " + ((Object)val).name + "."));
			RunManager.instance.levelCurrent = val;
			return true;
		}
	}
	internal static class RepoLibCompat
	{
		public static void Init()
		{
			Plugin.Log.LogDebug((object)"REPOLib detected.");
			BundleLoader.OnAllBundlesLoaded += Plugin.SkipMainMenu;
		}
	}
	internal enum SaveMode
	{
		ResetOnStartup,
		CreateOnStartup,
		Reuse
	}
	internal static class Utils
	{
		public static Level FindLevel(string name)
		{
			return RunManager.instance.levels.Find(delegate(Level level)
			{
				if (((Object)level).name == name)
				{
					return true;
				}
				if (((Object)level).name.StartsWith("Level - "))
				{
					string name2 = ((Object)level).name;
					int length = "Level - ".Length;
					return name2.Substring(length, name2.Length - length) == name;
				}
				return false;
			});
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}