Decompiled source of SoundAPI DunGen Fix v0.1.1

BepInEx/patchers/SoundAPIDunGenFix/SoundAPIDunGenFix.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using Mono.Cecil;
using Mono.Collections.Generic;

[assembly: AssemblyTitle("SoundAPI DunGen Fix")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.1.0.0")]
namespace SoundAPIDunGenFix;

public static class Patcher
{
	private static readonly string[] Types = new string[3] { "DunGen.RuntimeDungeon", "DunGen.DungeonGenerator", "DunGen.Graph.DungeonFlow" };

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

	public static void Patch(AssemblyDefinition assembly)
	{
		ManualLogSource val = Logger.CreateLogSource("SoundAPI DunGen Fix");
		try
		{
			string text = Path.Combine(Paths.ManagedPath, "DunGen.dll");
			if (!File.Exists(text))
			{
				val.LogInfo((object)"No separate DunGen.dll; no forwarding needed.");
				return;
			}
			AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly(text);
			try
			{
				int num = Apply(assembly, val2);
				val.LogInfo((object)("Added " + num + " DunGen type forwarders for legacy SoundAPI references (in memory only)."));
			}
			finally
			{
				((IDisposable)val2)?.Dispose();
			}
		}
		catch (Exception ex)
		{
			val.LogError((object)("Compatibility patch could not be applied: " + ex));
		}
	}

	public static int Apply(AssemblyDefinition assembly, AssemblyDefinition dungen)
	{
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Expected O, but got Unknown
		if (((AssemblyNameReference)assembly.Name).Name != "Assembly-CSharp" || ((AssemblyNameReference)dungen.Name).Name != "DunGen")
		{
			throw new InvalidOperationException("Unexpected assembly identity.");
		}
		List<TypeDefinition> list = new List<TypeDefinition>();
		string[] types = Types;
		foreach (string text in types)
		{
			if (assembly.MainModule.GetType(text) != null)
			{
				continue;
			}
			ExportedType val = null;
			Enumerator<ExportedType> enumerator = assembly.MainModule.ExportedTypes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ExportedType current = enumerator.Current;
					if (current.FullName == text)
					{
						val = current;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (val != null)
			{
				if (!val.IsForwarder || val.Scope.Name != "DunGen")
				{
					throw new InvalidOperationException("Conflicting exported type: " + text);
				}
				continue;
			}
			TypeDefinition type = dungen.MainModule.GetType(text);
			if (type == null || !type.IsPublic)
			{
				throw new InvalidOperationException("Required public type missing: " + text);
			}
			list.Add(type);
		}
		if (list.Count == 0)
		{
			return 0;
		}
		RequireField(dungen, "DunGen.RuntimeDungeon", "Generator", "DunGen.DungeonGenerator");
		RequireField(dungen, "DunGen.DungeonGenerator", "DungeonFlow", "DunGen.Graph.DungeonFlow");
		AssemblyNameReference val2 = null;
		Enumerator<AssemblyNameReference> enumerator2 = assembly.MainModule.AssemblyReferences.GetEnumerator();
		try
		{
			while (enumerator2.MoveNext())
			{
				AssemblyNameReference current2 = enumerator2.Current;
				if (current2.FullName == ((AssemblyNameReference)dungen.Name).FullName)
				{
					val2 = current2;
				}
			}
		}
		finally
		{
			((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
		}
		if (val2 == null)
		{
			val2 = AssemblyNameReference.Parse(((AssemblyNameReference)dungen.Name).FullName);
			assembly.MainModule.AssemblyReferences.Add(val2);
		}
		foreach (TypeDefinition item in list)
		{
			ExportedType val3 = new ExportedType(((TypeReference)item).Namespace, ((MemberReference)item).Name, assembly.MainModule, (IMetadataScope)(object)val2);
			val3.Attributes = (TypeAttributes)2097153;
			assembly.MainModule.ExportedTypes.Add(val3);
		}
		return list.Count;
	}

	private static void RequireField(AssemblyDefinition assembly, string typeName, string fieldName, string fieldType)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition type = assembly.MainModule.GetType(typeName);
		if (type != null)
		{
			Enumerator<FieldDefinition> enumerator = type.Fields.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					FieldDefinition current = enumerator.Current;
					if (((MemberReference)current).Name == fieldName && ((MemberReference)((FieldReference)current).FieldType).FullName == fieldType && current.IsPublic && !current.IsStatic)
					{
						return;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}
		throw new InvalidOperationException("Required field missing or incompatible: " + typeName + "." + fieldName);
	}
}