Decompiled source of AutoStart v1.1.1

AutoStart.dll

Decompiled 9 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using AutoStart.Core;
using AutoStart.Core.Lobby;
using AutoStart.Patch;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.CompilerServices;
using FastStartup;
using FastStartup.Config;
using GameNetcodeStuff;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AutoStart")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+294443216747e9cbad8758752bca757cb9cd0397")]
[assembly: AssemblyProduct("AutoStart")]
[assembly: AssemblyTitle("AutoStart")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace AutoStart
{
	[BepInPlugin("qwbarch.AutoStart", "AutoStart", "1.1.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		internal const string PluginId = "qwbarch.AutoStart";

		internal const string PluginName = "AutoStart";

		internal const string PluginVersion = "1.1.1";

		private void Awake()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			Logger.LogInfo("Loading AutoStart.");
			LockFile.WithLock(delegate
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				ConfigEntry<LaunchMode> autoLaunchMode = Plugin.Config.AutoLaunchMode;
				LaunchMode val2 = (LaunchMode)1;
				((ConfigEntryBase)autoLaunchMode).SetSerializedValue(((object)(LaunchMode)(ref val2)).ToString());
				Config.InitConfig((BaseUnityPlugin)(object)this);
			});
			if (Config.AutoStart.Enabled.Value)
			{
				UniTaskExtensions.Forget(LobbyHost.Start());
				Harmony val = new Harmony("qwbarch.AutoStart");
				val.PatchAll(typeof(StartGame));
			}
			else
			{
				Logger.LogInfo("AutoStart is disabled.");
			}
		}
	}
}
namespace AutoStart.Patch
{
	internal static class StartGame
	{
		private static int ConnectedPlayers;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		private static async void StartGameWhenReady()
		{
			SceneManager.GetSceneByName("MainMenu");
			while (true)
			{
				Scene sceneByName = SceneManager.GetSceneByName("MainMenu");
				if (((Scene)(ref sceneByName)).isLoaded)
				{
					break;
				}
				await Task.Yield();
			}
			MenuManager menuManager = Object.FindObjectOfType<MenuManager>();
			if (LobbyHost.IsHosting)
			{
				LockFile.WithLock(delegate
				{
					GameNetworkManager.Instance.currentSaveFileName = Config.AutoStart.SaveFile.Value;
				});
				menuManager.ConfirmHostButton();
			}
			else
			{
				UniTaskExtensions.Forget(LobbyParticipant.JoinLobby(menuManager));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		private static void SetLobbyHostReady(PlayerControllerB __instance)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)__instance).IsHost && Config.AutoPullLever.Enabled.Value)
			{
				if (Config.AutoPullLever.PlayersRequired.Value == 0)
				{
					StartOfRound.Instance.StartGame();
				}
				else
				{
					UniTaskExtensions.Forget(LobbyHost.SetLobbyReady());
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "OnClientConnect")]
		private static void IncrementPlayerCount(StartOfRound __instance)
		{
			if (((NetworkBehaviour)__instance).IsHost && Config.AutoPullLever.Enabled.Value)
			{
				ConnectedPlayers++;
				if (ConnectedPlayers == Config.AutoPullLever.PlayersRequired.Value)
				{
					__instance.StartGame();
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "OnClientDisconnect")]
		private static void DecrementPlayerCount(StartOfRound __instance)
		{
			if (((NetworkBehaviour)__instance).IsHost && Config.AutoPullLever.Enabled.Value)
			{
				ConnectedPlayers--;
			}
		}
	}
}
namespace AutoStart.Core
{
	internal static class Config
	{
		internal static class AutoStart
		{
			internal const string Section = "AutoStart";

			internal static ConfigEntry<bool> Enabled;

			internal static ConfigEntry<string> SaveFile;
		}

		internal static class AutoPullLever
		{
			internal const string Section = "AutoPullLever";

			internal static ConfigEntry<bool> Enabled;

			internal static ConfigEntry<int> PlayersRequired;
		}

		private static readonly string[] SaveFiles = new string[4] { "LCSaveFile1", "LCSaveFile2", "LCSaveFile3", "LCChallengeFile" };

		internal static void InitConfig(BaseUnityPlugin plugin)
		{
			AutoStart.Enabled = plugin.Config.Bind<bool>("AutoStart", "Enabled", true, "Whether or not the plugin should be enabled.");
			AutoStart.SaveFile = plugin.Config.Bind<string>("AutoStart", "SaveFile", "LCSaveFile1", "Possible vanilla values: " + string.Join(", ", SaveFiles));
			AutoPullLever.Enabled = plugin.Config.Bind<bool>("AutoPullLever", "Enabled", true, "Whether or not the start lever should be automatically pulled.");
			AutoPullLever.PlayersRequired = plugin.Config.Bind<int>("AutoPullLever", "PlayersRequired", 0, "Required number of players in the lobby for the lever to be pulled (excluding the host).");
		}
	}
	internal static class LockFile
	{
		public static void WithLock(Action action)
		{
			using EventWaitHandle eventWaitHandle = new EventWaitHandle(initialState: true, EventResetMode.AutoReset, "qwbarch.AutoStart");
			try
			{
				eventWaitHandle.WaitOne();
				action();
			}
			finally
			{
				eventWaitHandle.Set();
			}
		}
	}
	internal static class Logger
	{
		private static readonly ManualLogSource Source = Logger.CreateLogSource("qwbarch.AutoStart");

		internal static void LogInfo(string message)
		{
			Source.LogInfo((object)message);
		}

		internal static void LogDebug(string message)
		{
			Source.LogDebug((object)message);
		}

		internal static void LogWarning(string message)
		{
			Source.LogWarning((object)message);
		}

		internal static void LogError(string message)
		{
			Source.LogError((object)message);
		}
	}
}
namespace AutoStart.Core.Lobby
{
	internal static class LobbyHost
	{
		[CompilerGenerated]
		private sealed class <SendReady>d__7 : IAsyncStateMachine
		{
			public int <>1__state;

			public AsyncUniTaskMethodBuilder <>t__builder;

			public TcpClient client;

			private NetworkStream <stream>5__1;

			private TaskAwaiter <>u__1;

			private void MoveNext()
			{
				int num = <>1__state;
				try
				{
					if (num != 0)
					{
					}
					try
					{
						if (num != 0)
						{
							<stream>5__1 = client.GetStream();
						}
						try
						{
							TaskAwaiter awaiter;
							if (num != 0)
							{
								awaiter = <stream>5__1.WriteAsync(new byte[0], 0, 0).GetAwaiter();
								if (!awaiter.IsCompleted)
								{
									num = (<>1__state = 0);
									<>u__1 = awaiter;
									<SendReady>d__7 <SendReady>d__ = this;
									((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted<TaskAwaiter, <SendReady>d__7>(ref awaiter, ref <SendReady>d__);
									return;
								}
							}
							else
							{
								awaiter = <>u__1;
								<>u__1 = default(TaskAwaiter);
								num = (<>1__state = -1);
							}
							awaiter.GetResult();
						}
						finally
						{
							if (num < 0 && <stream>5__1 != null)
							{
								((IDisposable)<stream>5__1).Dispose();
							}
						}
						<stream>5__1 = null;
					}
					finally
					{
						if (num < 0)
						{
							client.Close();
						}
					}
				}
				catch (Exception exception)
				{
					<>1__state = -2;
					((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(exception);
					return;
				}
				<>1__state = -2;
				((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult();
			}

			void IAsyncStateMachine.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				this.MoveNext();
			}

			[DebuggerHidden]
			private void SetStateMachine(IAsyncStateMachine stateMachine)
			{
			}

			void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
			{
				//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
				this.SetStateMachine(stateMachine);
			}
		}

		[CompilerGenerated]
		private sealed class <SetLobbyReady>d__8 : IAsyncStateMachine
		{
			public int <>1__state;

			public AsyncUniTaskMethodBuilder <>t__builder;

			private LinkedList<TcpClient>.Enumerator <>s__1;

			private TcpClient <client>5__2;

			private Awaiter <>u__1;

			private void MoveNext()
			{
				//IL_0098: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: 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_007a: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				try
				{
					if (num == 0)
					{
						goto IL_0034;
					}
					if (_IsHosting)
					{
						IsReady = true;
						<>s__1 = Clients.GetEnumerator();
						goto IL_0034;
					}
					goto end_IL_0007;
					IL_0034:
					try
					{
						if (num != 0)
						{
							goto IL_00c3;
						}
						Awaiter awaiter = <>u__1;
						<>u__1 = default(Awaiter);
						num = (<>1__state = -1);
						goto IL_00b3;
						IL_00c3:
						if (<>s__1.MoveNext())
						{
							<client>5__2 = <>s__1.Current;
							UniTask val = SendReady(<client>5__2);
							awaiter = ((UniTask)(ref val)).GetAwaiter();
							if (!((Awaiter)(ref awaiter)).IsCompleted)
							{
								num = (<>1__state = 0);
								<>u__1 = awaiter;
								<SetLobbyReady>d__8 <SetLobbyReady>d__ = this;
								((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted<Awaiter, <SetLobbyReady>d__8>(ref awaiter, ref <SetLobbyReady>d__);
								return;
							}
							goto IL_00b3;
						}
						goto end_IL_0034;
						IL_00b3:
						((Awaiter)(ref awaiter)).GetResult();
						<client>5__2 = null;
						goto IL_00c3;
						end_IL_0034:;
					}
					finally
					{
						if (num < 0)
						{
							((IDisposable)<>s__1).Dispose();
						}
					}
					<>s__1 = default(LinkedList<TcpClient>.Enumerator);
					Clients.Clear();
					end_IL_0007:;
				}
				catch (Exception exception)
				{
					<>1__state = -2;
					((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(exception);
					return;
				}
				<>1__state = -2;
				((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult();
			}

			void IAsyncStateMachine.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				this.MoveNext();
			}

			[DebuggerHidden]
			private void SetStateMachine(IAsyncStateMachine stateMachine)
			{
			}

			void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
			{
				//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
				this.SetStateMachine(stateMachine);
			}
		}

		[CompilerGenerated]
		private sealed class <Start>d__9 : IAsyncStateMachine
		{
			public int <>1__state;

			public AsyncUniTaskMethodBuilder <>t__builder;

			private TcpListener <listener>5__1;

			private TcpClient <client>5__2;

			private TcpClient <>s__3;

			private TaskAwaiter<TcpClient> <>u__1;

			private Awaiter <>u__2;

			private void MoveNext()
			{
				//IL_0110: Unknown result type (might be due to invalid IL or missing references)
				//IL_0115: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0152: Unknown result type (might be due to invalid IL or missing references)
				//IL_0157: Unknown result type (might be due to invalid IL or missing references)
				//IL_015f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0133: Unknown result type (might be due to invalid IL or missing references)
				//IL_0135: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				try
				{
					if ((uint)num <= 1u)
					{
						goto IL_006f;
					}
					<listener>5__1 = new TcpListener(IPAddress.Parse("127.0.0.1"), 7777);
					try
					{
						<listener>5__1.Start();
						_IsHosting = true;
						Logger.LogInfo("LobbyHost is enabled. Waiting for participants.");
					}
					catch (SocketException)
					{
						Logger.LogInfo("LobbyHost is disabled. Waiting for host to be ready before joining.");
					}
					if (_IsHosting)
					{
						goto IL_0199;
					}
					goto end_IL_0007;
					IL_006f:
					try
					{
						Awaiter awaiter;
						TaskAwaiter<TcpClient> awaiter2;
						if (num != 0)
						{
							if (num == 1)
							{
								awaiter = <>u__2;
								<>u__2 = default(Awaiter);
								num = (<>1__state = -1);
								goto IL_016e;
							}
							awaiter2 = <listener>5__1.AcceptTcpClientAsync().GetAwaiter();
							if (!awaiter2.IsCompleted)
							{
								num = (<>1__state = 0);
								<>u__1 = awaiter2;
								<Start>d__9 <Start>d__ = this;
								((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted<TaskAwaiter<TcpClient>, <Start>d__9>(ref awaiter2, ref <Start>d__);
								return;
							}
						}
						else
						{
							awaiter2 = <>u__1;
							<>u__1 = default(TaskAwaiter<TcpClient>);
							num = (<>1__state = -1);
						}
						<>s__3 = awaiter2.GetResult();
						<client>5__2 = <>s__3;
						<>s__3 = null;
						if (IsReady)
						{
							UniTask val = SendReady(<client>5__2);
							awaiter = ((UniTask)(ref val)).GetAwaiter();
							if (!((Awaiter)(ref awaiter)).IsCompleted)
							{
								num = (<>1__state = 1);
								<>u__2 = awaiter;
								<Start>d__9 <Start>d__ = this;
								((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted<Awaiter, <Start>d__9>(ref awaiter, ref <Start>d__);
								return;
							}
							goto IL_016e;
						}
						Clients.AddLast(<client>5__2);
						goto IL_0189;
						IL_016e:
						((Awaiter)(ref awaiter)).GetResult();
						goto IL_0189;
						IL_0189:
						<client>5__2 = null;
					}
					catch (SocketException)
					{
					}
					goto IL_0199;
					IL_0199:
					bool flag = true;
					goto IL_006f;
					end_IL_0007:;
				}
				catch (Exception exception)
				{
					<>1__state = -2;
					<listener>5__1 = null;
					((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(exception);
					return;
				}
				<>1__state = -2;
				<listener>5__1 = null;
				((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult();
			}

			void IAsyncStateMachine.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				this.MoveNext();
			}

			[DebuggerHidden]
			private void SetStateMachine(IAsyncStateMachine stateMachine)
			{
			}

			void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
			{
				//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
				this.SetStateMachine(stateMachine);
			}
		}

		internal const string Host = "127.0.0.1";

		internal const int Port = 7777;

		private static readonly LinkedList<TcpClient> Clients = new LinkedList<TcpClient>();

		private static bool _IsHosting = false;

		private static bool IsReady = false;

		public static bool IsHosting => _IsHosting;

		[AsyncStateMachine(typeof(<SendReady>d__7))]
		[DebuggerStepThrough]
		private static UniTask SendReady(TcpClient client)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			<SendReady>d__7 <SendReady>d__ = new <SendReady>d__7();
			<SendReady>d__.<>t__builder = AsyncUniTaskMethodBuilder.Create();
			<SendReady>d__.client = client;
			<SendReady>d__.<>1__state = -1;
			((AsyncUniTaskMethodBuilder)(ref <SendReady>d__.<>t__builder)).Start<<SendReady>d__7>(ref <SendReady>d__);
			return ((AsyncUniTaskMethodBuilder)(ref <SendReady>d__.<>t__builder)).Task;
		}

		[AsyncStateMachine(typeof(<SetLobbyReady>d__8))]
		[DebuggerStepThrough]
		public static UniTask SetLobbyReady()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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)
			<SetLobbyReady>d__8 <SetLobbyReady>d__ = new <SetLobbyReady>d__8();
			<SetLobbyReady>d__.<>t__builder = AsyncUniTaskMethodBuilder.Create();
			<SetLobbyReady>d__.<>1__state = -1;
			((AsyncUniTaskMethodBuilder)(ref <SetLobbyReady>d__.<>t__builder)).Start<<SetLobbyReady>d__8>(ref <SetLobbyReady>d__);
			return ((AsyncUniTaskMethodBuilder)(ref <SetLobbyReady>d__.<>t__builder)).Task;
		}

		[AsyncStateMachine(typeof(<Start>d__9))]
		[DebuggerStepThrough]
		public static UniTask Start()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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)
			<Start>d__9 <Start>d__ = new <Start>d__9();
			<Start>d__.<>t__builder = AsyncUniTaskMethodBuilder.Create();
			<Start>d__.<>1__state = -1;
			((AsyncUniTaskMethodBuilder)(ref <Start>d__.<>t__builder)).Start<<Start>d__9>(ref <Start>d__);
			return ((AsyncUniTaskMethodBuilder)(ref <Start>d__.<>t__builder)).Task;
		}
	}
	internal static class LobbyParticipant
	{
		[CompilerGenerated]
		private sealed class <JoinLobby>d__0 : IAsyncStateMachine
		{
			public int <>1__state;

			public AsyncUniTaskMethodBuilder <>t__builder;

			public MenuManager menuManager;

			private TcpClient <tcpClient>5__1;

			private NetworkStream <stream>5__2;

			private TaskAwaiter<int> <>u__1;

			private void MoveNext()
			{
				int num = <>1__state;
				try
				{
					TaskAwaiter<int> awaiter;
					if (num != 0)
					{
						<tcpClient>5__1 = new TcpClient("127.0.0.1", 7777);
						<stream>5__2 = <tcpClient>5__1.GetStream();
						awaiter = <stream>5__2.ReadAsync(new byte[0], 0, 0).GetAwaiter();
						if (!awaiter.IsCompleted)
						{
							num = (<>1__state = 0);
							<>u__1 = awaiter;
							<JoinLobby>d__0 <JoinLobby>d__ = this;
							((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted<TaskAwaiter<int>, <JoinLobby>d__0>(ref awaiter, ref <JoinLobby>d__);
							return;
						}
					}
					else
					{
						awaiter = <>u__1;
						<>u__1 = default(TaskAwaiter<int>);
						num = (<>1__state = -1);
					}
					awaiter.GetResult();
					Logger.LogInfo("Lobby is ready! Attempting to join the game.");
					menuManager.StartAClient();
				}
				catch (Exception exception)
				{
					<>1__state = -2;
					<tcpClient>5__1 = null;
					<stream>5__2 = null;
					((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(exception);
					return;
				}
				<>1__state = -2;
				<tcpClient>5__1 = null;
				<stream>5__2 = null;
				((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult();
			}

			void IAsyncStateMachine.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				this.MoveNext();
			}

			[DebuggerHidden]
			private void SetStateMachine(IAsyncStateMachine stateMachine)
			{
			}

			void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
			{
				//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
				this.SetStateMachine(stateMachine);
			}
		}

		[AsyncStateMachine(typeof(<JoinLobby>d__0))]
		[DebuggerStepThrough]
		public static UniTask JoinLobby(MenuManager menuManager)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			<JoinLobby>d__0 <JoinLobby>d__ = new <JoinLobby>d__0();
			<JoinLobby>d__.<>t__builder = AsyncUniTaskMethodBuilder.Create();
			<JoinLobby>d__.menuManager = menuManager;
			<JoinLobby>d__.<>1__state = -1;
			((AsyncUniTaskMethodBuilder)(ref <JoinLobby>d__.<>t__builder)).Start<<JoinLobby>d__0>(ref <JoinLobby>d__);
			return ((AsyncUniTaskMethodBuilder)(ref <JoinLobby>d__.<>t__builder)).Task;
		}
	}
}