Decompiled source of NoCartographyFade v1.2.1

NoCartographyFade.dll

Decompiled 15 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace NoCartographyFade;

[BepInPlugin("com.valkyrie.no_cartography_map_fade", "NoCartographyFade", "1.2.0")]
public class NoCartographyFade : BaseUnityPlugin
{
	public const string PluginGUID = "com.valkyrie.no_cartography_map_fade";

	public const string PluginName = "NoCartographyFade";

	public const string PluginVersion = "1.2.0";

	private const BindingFlags All = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

	private static ManualLogSource Log;

	private static Type minimapType;

	private static FieldInfo fExplored;

	private static FieldInfo fOthers;

	private static FieldInfo fSize;

	private static FieldInfo fFog;

	private static MethodInfo exploreXY;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Expected O, but got Unknown
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("mod.no_cartography_map_fade");
		minimapType = AccessTools.TypeByName("Minimap");
		if (minimapType == null)
		{
			Log.LogError((object)"Could not find the Minimap type. Nothing was patched.");
			return;
		}
		fExplored = minimapType.GetField("m_explored", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		fOthers = minimapType.GetField("m_exploredOthers", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		fSize = minimapType.GetField("m_textureSize", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		fFog = minimapType.GetField("m_fogTexture", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		exploreXY = minimapType.GetMethod("Explore", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
		{
			typeof(int),
			typeof(int)
		}, null);
		int num = 0;
		foreach (MethodInfo item in from x in minimapType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
			where x.Name == "AddSharedMapData" && x.GetMethodBody() != null
			select x)
		{
			try
			{
				Harmony obj = harmony;
				MethodInfo methodInfo = item;
				HarmonyMethod val = new HarmonyMethod(typeof(NoCartographyFade), "ReplaceExploreOthers", (Type[])null);
				obj.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (!CanPromote()) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(NoCartographyFade), "PromoteAfterRead", (Type[])null), val, (HarmonyMethod)null, (HarmonyMethod)null);
				num++;
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to patch " + Describe(item) + ": " + ex.Message));
			}
		}
		if (num == 0)
		{
			Log.LogError((object)"Minimap.AddSharedMapData was not found or could not be patched. Table reads will still fade.");
		}
		MethodInfo method = minimapType.GetMethod("ResetAndExplore", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
		{
			typeof(BitArray),
			typeof(BitArray)
		}, null);
		if (method == null)
		{
			Log.LogWarning((object)"Minimap.ResetAndExplore(BitArray, BitArray) was not found. Previously faded tiles will not be converted on load.");
		}
		else
		{
			try
			{
				harmony.Patch((MethodBase)method, new HarmonyMethod(typeof(NoCartographyFade), "MergeOnLoad", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				num++;
			}
			catch (Exception ex2)
			{
				Log.LogError((object)("Failed to patch " + Describe(method) + ": " + ex2.Message));
			}
		}
		if (!CanPromote())
		{
			Log.LogWarning((object)"Could not resolve Minimap fields/methods; live conversion of faded tiles is disabled.");
		}
		Log.LogInfo((object)("NoCartographyFade 1.2.0 loaded (" + num + " method(s) patched)."));
	}

	private static bool CanPromote()
	{
		return fExplored != null && fOthers != null && fSize != null && fFog != null && exploreXY != null;
	}

	private static IEnumerable<CodeInstruction> ReplaceExploreOthers(IEnumerable<CodeInstruction> instructions, MethodBase original)
	{
		List<CodeInstruction> list = instructions.ToList();
		int num = 0;
		foreach (CodeInstruction item in list)
		{
			if (item.opcode != OpCodes.Call && item.opcode != OpCodes.Callvirt)
			{
				continue;
			}
			MethodInfo methodInfo = item.operand as MethodInfo;
			if (!(methodInfo == null) && !(methodInfo.Name != "ExploreOthers") && !(methodInfo.DeclaringType != minimapType))
			{
				Type[] types = (from p in methodInfo.GetParameters()
					select p.ParameterType).ToArray();
				MethodInfo method = minimapType.GetMethod("Explore", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, types, null);
				if (method == null || method.ReturnType != methodInfo.ReturnType)
				{
					Log.LogWarning((object)("No Minimap.Explore overload matches " + Describe(methodInfo) + "; call left unchanged."));
					continue;
				}
				item.operand = method;
				num++;
			}
		}
		if (num == 0)
		{
			Log.LogWarning((object)("Found no ExploreOthers calls in " + Describe(original) + ". The game code may have changed."));
		}
		else
		{
			Log.LogInfo((object)("Replaced " + num + " ExploreOthers call(s) in " + Describe(original) + "."));
		}
		return list;
	}

	private static void PromoteAfterRead(object __instance)
	{
		try
		{
			BitArray bitArray = fExplored.GetValue(__instance) as BitArray;
			BitArray bitArray2 = fOthers.GetValue(__instance) as BitArray;
			if (bitArray == null || bitArray2 == null || bitArray.Length != bitArray2.Length)
			{
				return;
			}
			int num = (int)fSize.GetValue(__instance);
			if (num <= 0)
			{
				return;
			}
			BitArray bitArray3 = new BitArray(bitArray2);
			bitArray3.And(new BitArray(bitArray).Not());
			int[] array = new int[(bitArray3.Length + 31) / 32];
			bitArray3.CopyTo(array, 0);
			Func<int, int, bool> func = (Func<int, int, bool>)Delegate.CreateDelegate(typeof(Func<int, int, bool>), __instance, exploreXY);
			int num2 = 0;
			for (int i = 0; i < array.Length; i++)
			{
				int num3 = array[i];
				if (num3 == 0)
				{
					continue;
				}
				for (int j = 0; j < 32; j++)
				{
					if (((num3 >> j) & 1) != 0)
					{
						int num4 = i * 32 + j;
						if (num4 >= bitArray3.Length)
						{
							break;
						}
						if (func(num4 % num, num4 / num))
						{
							num2++;
						}
					}
				}
			}
			if (num2 > 0)
			{
				ApplyFog(__instance);
				Log.LogInfo((object)("Converted " + num2 + " previously faded tile(s) to explored."));
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Converting faded tiles failed: " + ex.Message));
		}
	}

	private static void ApplyFog(object minimap)
	{
		object value = fFog.GetValue(minimap);
		if (value != null)
		{
			MethodInfo method = value.GetType().GetMethod("Apply", Type.EmptyTypes);
			if (method != null)
			{
				method.Invoke(value, null);
			}
		}
	}

	private static void MergeOnLoad(BitArray __0, BitArray __1)
	{
		try
		{
			if (__0 != null && __1 != null && __0.Length == __1.Length)
			{
				__0.Or(__1);
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Merging faded tiles on load failed: " + ex.Message));
		}
	}

	private static string Describe(MethodBase m)
	{
		return m.DeclaringType.Name + "." + m.Name + "(" + string.Join(", ", (from p in m.GetParameters()
			select p.ParameterType.Name).ToArray()) + ")";
	}
}