Decompiled source of RandomRouteOnly v1.5.2

Index154.RandomRouteOnly.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 GameNetcodeStuff;
using HarmonyLib;
using LethalConstellations.PluginCore;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[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("Index154.RandomRouteOnly")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.5.2.0")]
[assembly: AssemblyInformationalVersion("1.5.2+1d502c149e8d606da9743d8b3fbe9723c13808b1")]
[assembly: AssemblyProduct("RandomRouteOnly")]
[assembly: AssemblyTitle("Index154.RandomRouteOnly")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.2.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.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 RandomRouteOnly
{
	internal class Rerolls : MonoBehaviour
	{
		public int rerolls = RandomRouteOnly.configManager.rerollsPerPlayer.Value;
	}
	public class ConfigManager
	{
		internal ConfigEntry<int> rerollsPerPlayer = null;

		internal ConfigEntry<bool> allowCompany = null;

		internal ConfigEntry<int> noRepeatCount = null;

		internal ConfigEntry<int> stayOnMoonDays = null;

		internal ConfigEntry<bool> constellations = null;

		internal void Setup(ConfigFile configFile)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			rerollsPerPlayer = configFile.Bind<int>("General", "Rerolls per player per quota", 1, new ConfigDescription("How many uses of the terminal command 'random' each player gets per quota", (AcceptableValueBase)null, Array.Empty<object>()));
			allowCompany = configFile.Bind<bool>("General", "Allow manually routing to Company", false, new ConfigDescription("If true, allows you to always route to the Company whenever you want", (AcceptableValueBase)null, Array.Empty<object>()));
			noRepeatCount = configFile.Bind<int>("General", "Number of previous moons to avoid", 0, new ConfigDescription("How many of the most recently routed to moons should be removed from the random routing pool. Useful for ensuring a certain level of variety. Set it to -1 if you want to avoid any and all moon repeats for as long as possible. In this case, once there are no more unvisited moons left to route to, the list of visited moons will be emptied again. Not tracked across game restarts", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 50), Array.Empty<object>()));
			stayOnMoonDays = configFile.Bind<int>("General", "Max consecutive days per moon", 1, new ConfigDescription("The number of days you can spend on a moon before the ship automatically travels to a new random moon. If you route to the Company before reaching this limit then the ship will return to the previous moon after leaving the Company. Not tracked across game restarts", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			constellations = configFile.Bind<bool>("Other", "Constellations compatibility", true, new ConfigDescription("Whether random routing should only select moons in the current constellations if LethalConstellations is enabled", (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	internal class ConstellationsCompat
	{
		internal static bool IsLevelInConstellation(SelectableLevel level)
		{
			return ClassMapper.IsLevelInConstellation(level, "");
		}
	}
	public class Helper
	{
		public static List<SelectableLevel> levels = new List<SelectableLevel>();

		public static bool constellationsLoaded = false;

		public static int daysOnLevel = 0;

		public static int previousLevel = -1;

		public static List<int> recentLevels = new List<int>();

		private static IEnumerator DelayStartGame(float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			StartMatchLever lever = Object.FindObjectOfType<StartMatchLever>();
			lever.StartGame();
		}

		public static int GetRandomLevel(ref StartOfRound __instance)
		{
			bool flag = __instance.gameStats.daysSpent == 0 && __instance.currentLevel.levelID == 0;
			List<int> list = new List<int>();
			List<int> list2 = new List<int>();
			RandomRouteOnly.Logger.LogInfo((object)"Selectable levels:");
			foreach (SelectableLevel level in levels)
			{
				bool flag2 = true;
				if ((Object)(object)level == (Object)(object)__instance.currentLevel && !flag)
				{
					flag2 = false;
				}
				if (constellationsLoaded && RandomRouteOnly.configManager.constellations.Value)
				{
					RandomRouteOnly.Logger.LogDebug((object)"Constellation support: Removing moon from random level selection");
					if (!ConstellationsCompat.IsLevelInConstellation(level))
					{
						flag2 = false;
					}
				}
				if (flag2)
				{
					list.Add(level.levelID);
				}
				if (!recentLevels.Contains(level.levelID) && flag2)
				{
					RandomRouteOnly.Logger.LogInfo((object)((Object)level).name);
					list2.Add(level.levelID);
				}
			}
			int num = 0;
			if (list2.Count < 1)
			{
				recentLevels.Clear();
				return list[Random.Range(0, list.Count)];
			}
			return list2[Random.Range(0, list2.Count)];
		}

		public static void FlyToLevel(ref StartOfRound __instance, bool randomLevel, bool autoLand)
		{
			if (!((NetworkBehaviour)__instance).NetworkManager.IsHost)
			{
				return;
			}
			bool flag = __instance.gameStats.daysSpent == 0 && __instance.currentLevel.levelID == 0;
			bool flag2 = false;
			int num = 3;
			if (daysOnLevel >= RandomRouteOnly.configManager.stayOnMoonDays.Value)
			{
				flag2 = true;
			}
			if (randomLevel)
			{
				num = 0;
			}
			if (__instance.currentLevel.levelID == 3 && !flag2)
			{
				num = previousLevel;
			}
			if ((randomLevel && flag2) || flag || num == -1)
			{
				num = GetRandomLevel(ref __instance);
			}
			if (!flag2 && num != 3 && __instance.currentLevel.levelID != 3 && !flag)
			{
				RandomRouteOnly.Logger.LogInfo((object)"Maximum days per moon not reached - Aborting reroute");
				return;
			}
			if (flag && num == 0 && RandomRouteOnly.configManager.noRepeatCount.Value != 0)
			{
				recentLevels.Add(num);
			}
			if (__instance.CanChangeLevels() && num != __instance.currentLevel.levelID)
			{
				__instance.ChangeLevelServerRpc(num, Object.FindObjectOfType<Terminal>().groupCredits);
				if (num == 3 && autoLand)
				{
					((MonoBehaviour)__instance).StartCoroutine(DelayStartGame(8f));
				}
			}
		}
	}
	[BepInPlugin("Index154.RandomRouteOnly", "RandomRouteOnly", "1.5.2")]
	public class RandomRouteOnly : BaseUnityPlugin
	{
		internal static ConfigManager configManager;

		internal static bool isLLLloaded;

		public static RandomRouteOnly Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			configManager = new ConfigManager();
			configManager.Setup(((BaseUnityPlugin)this).Config);
			Patch();
			Logger.LogInfo((object)"Index154.RandomRouteOnly has loaded!");
		}

		internal static void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("Index154.RandomRouteOnly");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Index154.RandomRouteOnly";

		public const string PLUGIN_NAME = "RandomRouteOnly";

		public const string PLUGIN_VERSION = "1.5.2";
	}
}
namespace RandomRouteOnly.Patches
{
	[HarmonyPatch(typeof(PlayerControllerB))]
	public class PlayerControllerBPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AddRerollValue(PlayerControllerB __instance)
		{
			Rerolls rerolls = ((Component)__instance).gameObject.AddComponent<Rerolls>();
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public class StartOfRoundPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void AutoRouteRandomDayOne(ref StartOfRound __instance)
		{
			if (Chainloader.PluginInfos.ContainsKey("com.github.darmuh.LethalConstellations"))
			{
				Helper.constellationsLoaded = true;
			}
			Helper.levels = new List<SelectableLevel>();
			TerminalKeyword val = Object.FindObjectOfType<Terminal>().terminalNodes.allKeywords[27];
			RandomRouteOnly.Logger.LogInfo((object)"Registered moons:");
			CompatibleNoun[] compatibleNouns = val.compatibleNouns;
			foreach (CompatibleNoun val2 in compatibleNouns)
			{
				if (val2.result.terminalOptions == null || val2.result.terminalOptions.Length <= 1)
				{
					continue;
				}
				int id = val2.result.terminalOptions[1].result.buyRerouteToMoon;
				if (id != 3 && val2.noun.word != "LiquidationLevel")
				{
					RandomRouteOnly.Logger.LogInfo((object)(val2.noun.word + " | ID = " + id));
					SelectableLevel item = __instance.levels.Where((SelectableLevel i) => i.levelID == id).FirstOrDefault();
					if (!Helper.levels.Contains(item))
					{
						Helper.levels.Add(item);
					}
				}
			}
			if (TimeOfDay.Instance.daysUntilDeadline == 0)
			{
				Helper.FlyToLevel(ref __instance, randomLevel: false, autoLand: false);
			}
			else if ((__instance.gameStats.daysSpent == 0 && __instance.currentLevel.levelID == 0) || __instance.currentLevel.levelID == 3)
			{
				Helper.FlyToLevel(ref __instance, randomLevel: true, autoLand: false);
			}
		}

		[HarmonyPatch("SetShipReadyToLand")]
		[HarmonyPostfix]
		private static void AutoRouteRandomNewDay(ref StartOfRound __instance)
		{
			if (__instance.currentLevel.levelID != 3)
			{
				if (Helper.previousLevel == __instance.currentLevel.levelID)
				{
					Helper.daysOnLevel++;
				}
				else
				{
					Helper.previousLevel = __instance.currentLevel.levelID;
					Helper.daysOnLevel = 1;
				}
			}
			if (TimeOfDay.Instance.daysUntilDeadline != 0)
			{
				Helper.FlyToLevel(ref __instance, randomLevel: true, autoLand: false);
				return;
			}
			PlayerControllerB[] allPlayerScripts = __instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				Rerolls component = ((Component)val).gameObject.GetComponent<Rerolls>();
				component.rerolls = RandomRouteOnly.configManager.rerollsPerPlayer.Value;
			}
			Helper.FlyToLevel(ref __instance, randomLevel: false, autoLand: true);
		}

		[HarmonyPatch("ChangeLevelServerRpc")]
		[HarmonyPrefix]
		private static void TrackLevelChanges(int levelID, int newGroupCreditsAmount, ref StartOfRound __instance)
		{
			if (!((NetworkBehaviour)__instance).NetworkManager.IsHost)
			{
				return;
			}
			if (levelID == 3)
			{
				Helper.previousLevel = __instance.currentLevel.levelID;
				return;
			}
			if (RandomRouteOnly.configManager.noRepeatCount.Value != 0 && Helper.previousLevel != levelID)
			{
				Helper.recentLevels.Add(levelID);
				if (RandomRouteOnly.configManager.noRepeatCount.Value < Helper.recentLevels.Count && RandomRouteOnly.configManager.noRepeatCount.Value != -1)
				{
					Helper.recentLevels.RemoveAt(0);
				}
				RandomRouteOnly.Logger.LogInfo((object)"Recently visited levels list:");
				foreach (int id in Helper.recentLevels)
				{
					SelectableLevel val = __instance.levels.Where((SelectableLevel i) => i.levelID == id).FirstOrDefault();
					RandomRouteOnly.Logger.LogInfo((object)((Object)val).name);
				}
			}
			if (__instance.currentLevel.levelID != levelID && Helper.previousLevel != levelID)
			{
				Helper.daysOnLevel = 0;
				Helper.previousLevel = levelID;
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	public class TerminalPatch
	{
		private static readonly TerminalNode noReroll = new TerminalNode
		{
			name = "noReroll",
			displayText = "\nYou have no rerolls left for this quota!\nLand the ship or let somebody else use the command.\n\nYour rerolls will be set to " + RandomRouteOnly.configManager.rerollsPerPlayer.Value + " at the start of the next quota\n\n\n",
			clearPreviousText = true
		};

		private static readonly TerminalNode noManualRoutesAllowed = new TerminalNode
		{
			name = "noManualRoutesAllowed",
			displayText = "\nYou are not allowed to manually fly to this moon!\nLand the ship or use the command 'random'\n\n\n",
			clearPreviousText = true
		};

		[HarmonyPatch("ParsePlayerSentence")]
		[HarmonyPostfix]
		private static TerminalNode RestrictRouteUsage(TerminalNode __result)
		{
			if (((Object)__result).name == "routeRandom" || ((Object)__result).name == "routeRandomFilterWeather")
			{
				Rerolls component = ((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<Rerolls>();
				if (component.rerolls < 1)
				{
					return noReroll;
				}
				component.rerolls--;
			}
			else if (((Object)__result).name.ToLowerInvariant().Contains("route") && !((Object)__result).name.Contains("Confirm") && (!((Object)__result).name.Contains("Company") || !RandomRouteOnly.configManager.allowCompany.Value))
			{
				return noManualRoutesAllowed;
			}
			return __result;
		}

		[HarmonyPatch("TextPostProcess")]
		[HarmonyPostfix]
		private static string AddRemainingRerollsText(string modifiedDisplayText, TerminalNode node, ref string __result)
		{
			if (__result.Contains("Routing autopilot to"))
			{
				Rerolls component = ((Component)GameNetworkManager.Instance.localPlayerController).gameObject.GetComponent<Rerolls>();
				string text = "s";
				if (component.rerolls == 1)
				{
					text = "";
				}
				__result = __result + "You have " + component.rerolls + " reroll" + text + " left for this quota\n\n\n";
			}
			return __result;
		}
	}
}