Decompiled source of WesleyInteriorsCompat v1.0.0

BepInEx\patchers\WesleyInteriorsCompat\WesleyInteriorsCompat.Preloader.dll

Decompiled 6 hours ago
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using Mono.Cecil;
using Mono.Collections.Generic;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace WesleyInteriorsCompat.Preloader;

public static class Patcher
{
	private const string MoonConfigFileName = "JacobG5.WesleyMoonScripts.cfg";

	public static IEnumerable<string> TargetDLLs => new string[1] { "Assembly-CSharp.dll" };

	public static void Initialize()
	{
		DisableWesleyMoonProgression();
	}

	public static void Patch(AssemblyDefinition assembly)
	{
		if (assembly == null || !string.Equals(((AssemblyNameReference)assembly.Name).Name, "Assembly-CSharp", StringComparison.Ordinal))
		{
			return;
		}
		try
		{
			string dunGenPath = Path.Combine(Paths.ManagedPath, "DunGen.dll");
			int num = AddDunGenForwarders(assembly, dunGenPath, WriteLog);
			WriteLog("Added " + num + " DunGen type forwarder(s) to Assembly-CSharp. No Wesley files were changed on disk.");
		}
		catch (Exception ex)
		{
			WriteLog("Could not add DunGen type forwarders: " + ex);
		}
	}

	public static int AddDunGenForwarders(AssemblyDefinition assembly, string dunGenPath, Action<string> log)
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Expected O, but got Unknown
		if (assembly == null)
		{
			throw new ArgumentNullException("assembly");
		}
		if (string.IsNullOrEmpty(dunGenPath) || !File.Exists(dunGenPath))
		{
			throw new FileNotFoundException("DunGen.dll was not found.", dunGenPath);
		}
		AssemblyDefinition val = null;
		try
		{
			val = AssemblyDefinition.ReadAssembly(dunGenPath);
			ModuleDefinition mainModule = assembly.MainModule;
			AssemblyNameReference val2 = FindOrAddDunGenReference(mainModule, val.Name);
			int num = 0;
			Enumerator<TypeDefinition> enumerator = val.MainModule.Types.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					if (current.IsPublic && IsDunGenNamespace(((TypeReference)current).Namespace))
					{
						if (ContainsDirectType(mainModule, ((TypeReference)current).Namespace, ((MemberReference)current).Name))
						{
							Log(log, "Skipped a conflicting Assembly-CSharp type: " + ((MemberReference)current).FullName);
						}
						else if (!ContainsForwarder(mainModule, ((TypeReference)current).Namespace, ((MemberReference)current).Name))
						{
							ExportedType val3 = new ExportedType(((TypeReference)current).Namespace, ((MemberReference)current).Name, mainModule, (IMetadataScope)(object)val2);
							val3.Attributes = (TypeAttributes)2097153;
							mainModule.ExportedTypes.Add(val3);
							num++;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			return num;
		}
		finally
		{
			if (val != null)
			{
				val.Dispose();
			}
		}
	}

	private static AssemblyNameReference FindOrAddDunGenReference(ModuleDefinition targetModule, AssemblyNameDefinition sourceAssemblyName)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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_006b: Expected O, but got Unknown
		Enumerator<AssemblyNameReference> enumerator = targetModule.AssemblyReferences.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				AssemblyNameReference current = enumerator.Current;
				if (string.Equals(current.Name, ((AssemblyNameReference)sourceAssemblyName).Name, StringComparison.Ordinal))
				{
					return current;
				}
			}
		}
		finally
		{
			((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
		}
		AssemblyNameReference val = new AssemblyNameReference(((AssemblyNameReference)sourceAssemblyName).Name, ((AssemblyNameReference)sourceAssemblyName).Version);
		targetModule.AssemblyReferences.Add(val);
		return val;
	}

	private static bool ContainsDirectType(ModuleDefinition module, string namespaceName, string typeName)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		Enumerator<TypeDefinition> enumerator = module.Types.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				TypeDefinition current = enumerator.Current;
				if (string.Equals(((TypeReference)current).Namespace, namespaceName, StringComparison.Ordinal) && string.Equals(((MemberReference)current).Name, typeName, StringComparison.Ordinal))
				{
					return true;
				}
			}
		}
		finally
		{
			((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
		}
		return false;
	}

	private static bool ContainsForwarder(ModuleDefinition module, string namespaceName, string typeName)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		Enumerator<ExportedType> enumerator = module.ExportedTypes.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				ExportedType current = enumerator.Current;
				if (current.DeclaringType == null && string.Equals(current.Namespace, namespaceName, StringComparison.Ordinal) && string.Equals(current.Name, typeName, StringComparison.Ordinal))
				{
					return true;
				}
			}
		}
		finally
		{
			((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
		}
		return false;
	}

	private static bool IsDunGenNamespace(string namespaceName)
	{
		return !string.IsNullOrEmpty(namespaceName) && (string.Equals(namespaceName, "DunGen", StringComparison.Ordinal) || namespaceName.StartsWith("DunGen.", StringComparison.Ordinal));
	}

	private static void DisableWesleyMoonProgression()
	{
		try
		{
			Directory.CreateDirectory(Paths.ConfigPath);
			string path = Path.Combine(Paths.ConfigPath, "JacobG5.WesleyMoonScripts.cfg");
			if (!File.Exists(path))
			{
				File.WriteAllText(path, "## Written by Wesley Interiors Compatibility Pack.\r\n## Keeps Wesley moon progression disabled.\r\n\r\n[Core]\r\n\r\nLockMoons = false\r\n", Encoding.UTF8);
				WriteLog("Created Wesley Moon Scripts configuration with progression locks disabled.");
				return;
			}
			string text = File.ReadAllText(path);
			string text2 = Regex.Replace(text, "(?m)^\\s*LockMoons\\s*=\\s*.*$", "LockMoons = false");
			if (string.Equals(text, text2, StringComparison.Ordinal))
			{
				if (!text2.EndsWith("\n", StringComparison.Ordinal))
				{
					text2 += Environment.NewLine;
				}
				text2 = text2 + "LockMoons = false" + Environment.NewLine;
			}
			if (!string.Equals(text, text2, StringComparison.Ordinal))
			{
				File.WriteAllText(path, text2, Encoding.UTF8);
				WriteLog("Set Wesley Moon Scripts LockMoons = false.");
			}
		}
		catch (Exception ex)
		{
			WriteLog("Could not update Wesley Moon Scripts configuration: " + ex.Message);
		}
	}

	private static void Log(Action<string> log, string message)
	{
		log?.Invoke(message);
	}

	private static void WriteLog(string message)
	{
		Console.WriteLine("[WesleyInteriorsCompat] " + message);
	}
}

BepInEx\plugins\WesleyInteriorsCompat\WesleyInteriorsCompat.dll

Decompiled 6 hours ago
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using LethalLevelLoader;
using UnityEngine;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace WesleyInteriorsCompat;

[BepInPlugin("Christian.WesleyInteriorsCompat", "Wesley Interiors Compatibility Pack", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class WesleyInteriorsCompatPlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Plugin), "CompleteSetup")]
	private static class CompleteSetupPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Instance.ApplyWesleyMoonOverrides();
			}
		}
	}

	[HarmonyPatch(typeof(Plugin), "LobbyInitialized")]
	private static class LobbyInitializedPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Instance.ApplyWesleyMoonOverrides();
				Instance.TryUpdateTerminalCatalogue();
			}
		}
	}

	[HarmonyPatch(typeof(Terminal), "Start")]
	private static class TerminalStartPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Instance.ApplyWesleyMoonOverrides();
				Instance.TryUpdateTerminalCatalogue();
			}
		}
	}

	[HarmonyPatch(typeof(DungeonManager), "GetValidExtendedDungeonFlows")]
	private static class VowRubberRoomsPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ExtendedLevel extendedLevel, ref List<ExtendedDungeonFlowWithRarity> __result)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Instance.ForceVowToRubberRooms(extendedLevel, ref __result);
			}
		}
	}

	public const string PluginGuid = "Christian.WesleyInteriorsCompat";

	public const string PluginName = "Wesley Interiors Compatibility Pack";

	public const string PluginVersion = "1.0.0";

	private static readonly HashSet<string> WesleyMoonNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
	{
		"trite", "oldred", "duckstroid14", "filitrios", "gratar", "etern", "dreck", "release", "motra", "calist",
		"alcatras", "fissionc", "berunah", "faith", "crowd", "lecaro", "demetrica", "gloom", "roart", "thalasso",
		"cosmocos", "hyx", "atlantica", "infernis", "infernus", "extort", "desolation", "narcotic", "cubatres", "empra",
		"asteroid13", "hyve", "repress", "utril", "descent", "acidir", "junic", "core", "polarus", "galetry",
		"end"
	};

	internal static WesleyInteriorsCompatPlugin Instance;

	private ConfigEntry<bool> forceVowRubberRooms;

	private ConfigEntry<bool> makeWesleyMoonsFree;

	private bool terminalCatalogueUpdated;

	private bool vowOverrideLogged;

	private void Awake()
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Expected O, but got Unknown
		Instance = this;
		forceVowRubberRooms = ((BaseUnityPlugin)this).Config.Bind<bool>("Vow", "Force Rubber Rooms", true, "When enabled, Vow has a 100% chance to use the Rubber Rooms interior.");
		makeWesleyMoonsFree = ((BaseUnityPlugin)this).Config.Bind<bool>("Wesley Moons", "Always Unlock and Make Free", true, "Removes Wesley moon progression locks, unhides the moons, and sets their route prices to 0.");
		Harmony val = new Harmony("Christian.WesleyInteriorsCompat");
		val.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Wesley Interiors Compatibility Pack 1.0.0 loaded.");
	}

	private void Update()
	{
		if (!terminalCatalogueUpdated && Plugin.IsSetupComplete)
		{
			ApplyWesleyMoonOverrides();
			terminalCatalogueUpdated = TryUpdateTerminalCatalogue();
		}
	}

	internal void ApplyWesleyMoonOverrides()
	{
		if (makeWesleyMoonsFree == null || !makeWesleyMoonsFree.Value)
		{
			return;
		}
		List<ExtendedLevel> customExtendedLevels = PatchedContent.CustomExtendedLevels;
		if (customExtendedLevels == null)
		{
			return;
		}
		int num = 0;
		foreach (ExtendedLevel item in customExtendedLevels)
		{
			if (!((Object)(object)item == (Object)null) && IsWesleyMoon(item))
			{
				bool flag = false;
				if (item.IsRouteLocked)
				{
					item.IsRouteLocked = false;
					flag = true;
				}
				if (item.IsRouteHidden)
				{
					item.IsRouteHidden = false;
					flag = true;
				}
				if (item.RoutePrice != 0)
				{
					item.ForceSetRoutePrice(0);
					flag = true;
				}
				if (flag)
				{
					num++;
				}
			}
		}
		if (num > 0)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Unlocked and made free " + num + " Wesley moon(s)."));
		}
	}

	private bool TryUpdateTerminalCatalogue()
	{
		Terminal val = Object.FindObjectOfType<Terminal>();
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		List<ExtendedLevel> customExtendedLevels = PatchedContent.CustomExtendedLevels;
		if (customExtendedLevels == null)
		{
			return true;
		}
		List<SelectableLevel> list = new List<SelectableLevel>();
		if (val.moonsCatalogueList != null)
		{
			list.AddRange(val.moonsCatalogueList);
		}
		foreach (ExtendedLevel item in customExtendedLevels)
		{
			if (!((Object)(object)item == (Object)null) && IsWesleyMoon(item) && !((Object)(object)item.SelectableLevel == (Object)null) && !list.Contains(item.SelectableLevel))
			{
				list.Add(item.SelectableLevel);
			}
		}
		val.moonsCatalogueList = list.ToArray();
		return true;
	}

	private void ForceVowToRubberRooms(ExtendedLevel extendedLevel, ref List<ExtendedDungeonFlowWithRarity> results)
	{
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Expected O, but got Unknown
		if (forceVowRubberRooms == null || !forceVowRubberRooms.Value || (Object)(object)extendedLevel == (Object)null || !string.Equals(Normalize(extendedLevel.NumberlessPlanetName), "vow", StringComparison.Ordinal))
		{
			return;
		}
		ExtendedDungeonFlow val = null;
		List<ExtendedDungeonFlow> extendedDungeonFlows = PatchedContent.ExtendedDungeonFlows;
		if (extendedDungeonFlows != null)
		{
			foreach (ExtendedDungeonFlow item in extendedDungeonFlows)
			{
				if (!((Object)(object)item == (Object)null) && !((Object)(object)item.DungeonFlow == (Object)null))
				{
					string text = Normalize(item.DungeonName);
					if (text.Contains("rubberroom"))
					{
						val = item;
						break;
					}
				}
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Vow was not changed because LethalLevelLoader did not register a valid Rubber Rooms flow. Check the preloader messages above.");
			return;
		}
		results = new List<ExtendedDungeonFlowWithRarity>
		{
			new ExtendedDungeonFlowWithRarity(val, 10000)
		};
		if (!vowOverrideLogged)
		{
			vowOverrideLogged = true;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Vow is restricted to Rubber Rooms (100%).");
		}
	}

	private static bool IsWesleyMoon(ExtendedLevel level)
	{
		string item = Normalize(level.NumberlessPlanetName);
		if (WesleyMoonNames.Contains(item))
		{
			return true;
		}
		string text = Normalize(level.contentSourceName);
		return text.Contains("wesleysmoon") || text.Contains("magicwesley");
	}

	private static string Normalize(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return string.Empty;
		}
		char[] array = new char[value.Length];
		int length = 0;
		foreach (char c in value)
		{
			if (char.IsLetterOrDigit(c))
			{
				array[length++] = char.ToLowerInvariant(c);
			}
		}
		return new string(array, 0, length);
	}
}