Decompiled source of AutoLand v1.0.6

BepInEx/plugins/AutoLand.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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("AutoLand")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("自动 Host + 自动下降飞船(测试用)")]
[assembly: AssemblyFileVersion("1.0.6.0")]
[assembly: AssemblyInformationalVersion("1.0.6+befbf9246c4dc6e72fa5c9ed4189ed3fb26e3133")]
[assembly: AssemblyProduct("AutoLand")]
[assembly: AssemblyTitle("AutoLand")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 AutoLand
{
	[BepInPlugin("zyjdmmm.AutoLand", "AutoLand", "1.0.6")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static bool _started;

		private const string DefaultTargetMoon = "EXPERIMENTATION";

		private const int DefaultSaveSlot = 3;

		private const int SaveSlotCount = 3;

		private static readonly string[] SaveFileSuffixes = new string[3] { "", ".bac", ".moddata" };

		private static ConfigFile Settings;

		private static ConfigEntry<string> TargetMoon;

		private static ConfigEntry<int> SaveSlot;

		private void Awake()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Settings = new ConfigFile(Path.Combine(Paths.ConfigPath, "AutoLand.cfg"), true);
			TargetMoon = Settings.Bind<string>("AutoLand", "TargetMoon", "EXPERIMENTATION", "默认降落月亮。可填写 MARCH、EXPERIMENTATION、TITAN,也可以填写其他可用月亮名称。");
			SaveSlot = Settings.Bind<int>("AutoLand", "SaveSlot", 3, "自动 Host 使用的存档槽,只能是 1、2 或 3。默认值为 3。");
			Log.LogInfo((object)"AutoLand v1.0.6 loaded");
			Harmony val = new Harmony("zyjdmmm.AutoLand");
			try
			{
				val.PatchAll(typeof(MenuManagerPatch));
			}
			catch (Exception ex)
			{
				Log.LogError((object)("MenuManagerPatch failed: " + ex.Message));
			}
			try
			{
				val.PatchAll(typeof(PreInitScenePatch));
			}
			catch (Exception ex2)
			{
				Log.LogError((object)("PreInitScenePatch failed: " + ex2.Message));
			}
		}

		private static bool SelectAutomationSaveSlot()
		{
			GameNetworkManager instance = GameNetworkManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				Log.LogError((object)"GameNetworkManager is not available");
				return false;
			}
			int num = ((SaveSlot == null) ? 3 : SaveSlot.Value);
			if (num < 1 || num > 3)
			{
				Log.LogWarning((object)$"Invalid SaveSlot={num}; using default slot {3}");
				num = 3;
			}
			string text = $"LCSaveFile{num}";
			bool num2 = HasSaveData(text);
			instance.currentSaveFileName = text;
			instance.saveFileNum = num;
			if (!num2)
			{
				instance.ResetSavedGameValues();
			}
			Log.LogInfo((object)$"Using save slot {num} ({text})");
			return true;
		}

		private static bool HasSaveData(string saveFileName)
		{
			string[] saveFileSuffixes = SaveFileSuffixes;
			foreach (string text in saveFileSuffixes)
			{
				if (File.Exists(Path.Combine(Application.persistentDataPath, saveFileName + text)))
				{
					return true;
				}
			}
			return false;
		}

		private static string GetTargetMoon()
		{
			string text = ((TargetMoon == null) ? "EXPERIMENTATION" : (TargetMoon.Value ?? "")).Trim();
			if (!string.IsNullOrEmpty(text))
			{
				return text;
			}
			return "EXPERIMENTATION";
		}

		internal static IEnumerator AutoHostAndLand()
		{
			yield return (object)new WaitForSeconds(2f);
			Log.LogInfo((object)"Setting online mode...");
			GameNetworkManager.Instance.disableSteam = false;
			yield return (object)new WaitForSeconds(0.5f);
			if (!SelectAutomationSaveSlot())
			{
				yield break;
			}
			Log.LogInfo((object)"Starting Host...");
			try
			{
				GameNetworkManager.Instance.StartHost();
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"StartHost failed: {arg}");
				yield break;
			}
			Log.LogInfo((object)"Waiting for ship scene...");
			float waitTimer = 0f;
			while (((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null || StartOfRound.Instance.allPlayerScripts.Length == 0) && waitTimer < 120f)
			{
				yield return null;
				waitTimer += Time.deltaTime;
			}
			if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null || StartOfRound.Instance.allPlayerScripts.Length == 0)
			{
				Log.LogError((object)"Timed out waiting for ship scene");
				yield break;
			}
			yield return (object)new WaitForSeconds(3f);
			string targetMoon = GetTargetMoon();
			Log.LogInfo((object)("Selecting moon " + targetMoon + "..."));
			int num = FindMoonLevelId(targetMoon);
			if (num < 0)
			{
				Log.LogError((object)("Moon not found: " + targetMoon));
				yield break;
			}
			try
			{
				StartOfRound.Instance.ChangeLevel(num);
				Log.LogInfo((object)$"Selected moon {targetMoon} (levelID={num})");
			}
			catch (Exception arg2)
			{
				Log.LogError((object)$"ChangeLevel failed: {arg2}");
				yield break;
			}
			yield return (object)new WaitForSeconds(2f);
			Log.LogInfo((object)"Starting game...");
			try
			{
				StartOfRound.Instance.StartGame();
			}
			catch (Exception arg3)
			{
				Log.LogError((object)$"StartGame failed: {arg3}");
				yield break;
			}
			Log.LogInfo((object)"Waiting for ship to land...");
			waitTimer = 0f;
			while (!StartOfRound.Instance.shipHasLanded && waitTimer < 180f)
			{
				yield return null;
				waitTimer += Time.deltaTime;
			}
			Log.LogInfo((object)(StartOfRound.Instance.shipHasLanded ? "Ship landed; automation complete" : "Landing timed out"));
		}

		private static int FindMoonLevelId(string moonName)
		{
			SelectableLevel[] array = StartOfRound.Instance?.levels;
			if (array == null)
			{
				return -1;
			}
			SelectableLevel[] array2 = array;
			foreach (SelectableLevel val in array2)
			{
				if ((Object)(object)val != (Object)null && val.PlanetName != null && val.PlanetName.IndexOf(moonName, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return val.levelID;
				}
			}
			List<string> list = new List<string>();
			array2 = array;
			foreach (SelectableLevel val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					list.Add($"{val2.levelID}:{val2.PlanetName}");
				}
			}
			Log.LogWarning((object)("Moon not found: " + moonName + "; available: " + string.Join(", ", list)));
			return -1;
		}
	}
	[HarmonyPatch(typeof(MenuManager), "Start")]
	internal static class MenuManagerPatch
	{
		private static void Postfix(MenuManager __instance)
		{
			try
			{
				if (!__instance.isInitScene && !Plugin._started)
				{
					Plugin._started = true;
					Plugin.Log.LogInfo((object)"Main menu ready; starting AutoLand");
					((MonoBehaviour)(((Object)(object)GameNetworkManager.Instance != (Object)null) ? ((object)GameNetworkManager.Instance) : ((object)__instance))).StartCoroutine(Plugin.AutoHostAndLand());
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"MenuManagerPatch failed: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(PreInitSceneScript), "Start")]
	internal static class PreInitScenePatch
	{
		private static void Postfix(PreInitSceneScript __instance)
		{
			try
			{
				((MonoBehaviour)__instance).StartCoroutine(ChooseOnlineDelayed(__instance));
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"PreInitScenePatch failed: {arg}");
			}
		}

		private static IEnumerator ChooseOnlineDelayed(PreInitSceneScript instance)
		{
			yield return (object)new WaitForSeconds(1.5f);
			try
			{
				instance.ChooseLaunchOption(true);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Choosing online mode failed: {arg}");
			}
		}
	}
	internal static class PluginInfo
	{
		public const string PLUGIN_GUID = "zyjdmmm.AutoLand";

		public const string PLUGIN_NAME = "AutoLand";

		public const string PLUGIN_VERSION = "1.0.6";
	}
}