Decompiled source of PlanBuild Mac v1.0.0

plugins/PlanBuild-Mac.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("PlanBuild-Mac")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PlanBuild-Mac")]
[assembly: AssemblyTitle("PlanBuild-Mac")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 PlanBuildMac
{
	[BepInPlugin("PlanBuild-Mac", "PlanBuild Mac", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "PlanBuild-Mac";

		public const string Version = "1.0.0";

		private const string PlanBuildGuid = "marcopogo.PlanBuild";

		private static readonly string[] BundleMaterials = new string[2] { "RuneMaterial", "BlueprintSnapIconMaterial" };

		internal static ManualLogSource Log;

		private static readonly HashSet<Shader> modCopies = new HashSet<Shader>();

		private static readonly Dictionary<Shader, bool> tested = new Dictionary<Shader, bool>();

		private static RenderTexture probeTarget;

		private static Texture2D probePixels;

		private void Awake()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			Log = ((BaseUnityPlugin)this).Logger;
			if ((int)Application.platform != 1)
			{
				Log.LogInfo((object)"Not on macOS, so PlanBuild needs no fix here: staying idle");
				return;
			}
			string value = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Blueprint folder", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Documents", "Valheim Blueprints"), "Where PlanBuild saves and looks for blueprints on Mac. Keep it outside the BepInEx folder: PlanBuild cuts the BepInEx path off the files it finds there and then can't open them").Value;
			try
			{
				FixFolders(value);
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Could not set PlanBuild's blueprint folder: " + ex));
			}
			Material[] array = BlueprintMaterials();
			foreach (Material val in array)
			{
				modCopies.Add(val.shader);
			}
			FixMaterials();
			SceneManager.sceneLoaded += delegate
			{
				FixMaterials();
			};
		}

		private static void FixFolders(string folder)
		{
			BaseUnityPlugin instance = Chainloader.PluginInfos["marcopogo.PlanBuild"].Instance;
			ConfigEntry<string> val = default(ConfigEntry<string>);
			ConfigEntry<string> val2 = default(ConfigEntry<string>);
			if (!instance.Config.TryGetEntry<string>("Directories", "Search directory", ref val) || !instance.Config.TryGetEntry<string>("Directories", "Save directory", ref val2))
			{
				Log.LogWarning((object)"PlanBuild changed: its blueprint folder settings are gone, leaving it as it is");
				return;
			}
			if (Path.IsPathRooted(val.Value) && Path.IsPathRooted(val2.Value))
			{
				Log.LogInfo((object)("PlanBuild already uses full paths (" + val.Value + "), leaving them as they are"));
				return;
			}
			Directory.CreateDirectory(folder);
			string fullPath = Path.GetFullPath(val2.Value);
			if (!Path.IsPathRooted(val2.Value) && Directory.Exists(fullPath))
			{
				string[] files = Directory.GetFiles(fullPath);
				foreach (string text in files)
				{
					string text2 = Path.Combine(folder, Path.GetFileName(text));
					if (!File.Exists(text2))
					{
						File.Copy(text, text2);
						Log.LogInfo((object)("Copied " + Path.GetFileName(text) + " out of the app to " + folder));
					}
				}
			}
			val.Value = folder;
			val2.Value = folder;
			Log.LogInfo((object)("Blueprint folder: " + folder));
			MethodInfo methodInfo = ((object)instance).GetType().Assembly.GetType("PlanBuild.Blueprints.BlueprintSync")?.GetMethod("GetLocalBlueprints", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (methodInfo == null)
			{
				Log.LogWarning((object)"PlanBuild changed: blueprints load on its Refresh button or the next start");
			}
			else
			{
				methodInfo.Invoke(null, null);
			}
		}

		private static void FixMaterials()
		{
			try
			{
				List<Material> list = (from m in BlueprintMaterials()
					where modCopies.Contains(m.shader)
					select m).ToList();
				if (list.Count == 0)
				{
					return;
				}
				Shader val = (from s in Resources.FindObjectsOfTypeAll<Shader>()
					where ((Object)s).name == "Standard" && s.isSupported && !modCopies.Contains(s)
					select s).FirstOrDefault((Func<Shader, bool>)Works);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				foreach (Material item in list)
				{
					int renderQueue = item.renderQueue;
					Shader shader = item.shader;
					item.shader = val;
					item.renderQueue = renderQueue;
					Log.LogInfo((object)$"Material {((Object)item).name} #{((Object)item).GetInstanceID()}: Standard #{((Object)shader).GetInstanceID()} -> Standard #{((Object)val).GetInstanceID()}");
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex);
			}
		}

		private static bool Works(Shader s)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			if (tested.TryGetValue(s, out var value))
			{
				return value;
			}
			if ((Object)(object)probeTarget == (Object)null)
			{
				probeTarget = new RenderTexture(4, 4, 24, (RenderTextureFormat)0);
				probePixels = new Texture2D(4, 4, (TextureFormat)4, false);
			}
			Material val = new Material(s);
			RenderTexture active = RenderTexture.active;
			bool flag;
			try
			{
				if (val.passCount == 0)
				{
					flag = (tested[s] = false);
					flag = flag;
				}
				else
				{
					RenderTexture.active = probeTarget;
					GL.Clear(true, true, Color.clear);
					Graphics.Blit((Texture)(object)Texture2D.whiteTexture, probeTarget, val, 0);
					RenderTexture.active = probeTarget;
					probePixels.ReadPixels(new Rect(0f, 0f, 4f, 4f), 0, 0, false);
					Color pixel = probePixels.GetPixel(2, 2);
					value = !(pixel.r > 0.9f) || !(pixel.g < 0.1f) || !(pixel.b > 0.9f);
					if (!value)
					{
						Log.LogInfo((object)$"Standard #{((Object)s).GetInstanceID()} from another mod draws pink here, skipping it");
					}
					bool flag3 = (tested[s] = value);
					flag = flag3;
				}
			}
			finally
			{
				RenderTexture.active = active;
				Object.Destroy((Object)(object)val);
			}
			return flag;
		}

		private static Material[] BlueprintMaterials()
		{
			return (from m in Resources.FindObjectsOfTypeAll<Material>()
				where (Object)(object)m.shader != (Object)null && BundleMaterials.Contains(((Object)m).name)
				select m).ToArray();
		}
	}
}