Decompiled source of SnowFix v1.0.0

SnowFix.dll

Decompiled 3 days ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[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("SnowFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SnowFix")]
[assembly: AssemblyTitle("SnowFix")]
[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 SnowFix
{
	[BepInPlugin("MrGay.SnowFix", "Snow Fix", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "MrGay.SnowFix";

		internal static ManualLogSource Log;

		internal static Shader PatchedShader;

		internal static bool UseShader = true;

		internal static ConfigEntry<bool> MountainDeepSnow;

		private void Awake()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			MountainDeepSnow = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "MountainDeepSnow", true, "Give Mountain terrain the Deep North deep-snow mask so it renders as white raised snow.");
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "snowfix_heightmap.bundle");
			if (File.Exists(text))
			{
				AssetBundle val = AssetBundle.LoadFromFile(text);
				if ((Object)(object)val != (Object)null)
				{
					Shader[] array = val.LoadAllAssets<Shader>();
					foreach (Shader val2 in array)
					{
						if (((Object)val2).name == "Custom/Heightmap")
						{
							PatchedShader = val2;
						}
					}
				}
			}
			Log.LogInfo((object)(((Object)(object)PatchedShader != (Object)null) ? "Loaded patched Custom/Heightmap shader" : "Patched shader NOT loaded"));
			new Harmony("MrGay.SnowFix").PatchAll();
		}

		internal static void Apply(Heightmap hm, bool patched)
		{
			Material value = Traverse.Create((object)hm).Field("m_materialInstance").GetValue<Material>();
			if (!((Object)(object)value == (Object)null) && !((Object)(object)PatchedShader == (Object)null))
			{
				Material value2 = Traverse.Create((object)hm).Field("m_material").GetValue<Material>();
				Shader val = (patched ? PatchedShader : value2.shader);
				if ((Object)(object)value.shader != (Object)(object)val)
				{
					value.shader = val;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Heightmap), "Regenerate")]
	public static class HeightmapShaderSwap
	{
		private static void Postfix(Heightmap __instance)
		{
			if (Plugin.UseShader)
			{
				Plugin.Apply(__instance, patched: true);
			}
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "GetBiomeHeight")]
	public static class MountainSnowMask
	{
		private static void Postfix(WorldGenerator __instance, Biome biome, float wx, float wy, ref Color mask, bool preGeneration)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if (!(!Plugin.MountainDeepSnow.Value || preGeneration) && (int)biome == 4 && mask.r == 0f && mask.g == 0f && mask.b == 0f && mask.a == 0f)
			{
				Color val = default(Color);
				__instance.GetBiomeHeight((Biome)64, wx, wy, ref val, false, true);
				mask = new Color(0f, Mathf.Min(val.g, 0.49f), 0f, 0f);
			}
		}
	}
	[HarmonyPatch(typeof(Heightmap), "GetBiome", new Type[]
	{
		typeof(Vector3),
		typeof(float),
		typeof(bool)
	})]
	public static class ExactBiomeAtEdges
	{
		private static bool Prefix(Heightmap __instance, Vector3 point, float oceanLevel, bool waterAlwaysOcean, ref Biome __result)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_0075: Expected I4, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			BiomeSector[] value = Traverse.Create((object)__instance).Field("m_cornerBiomes").GetValue<BiomeSector[]>();
			if (value == null || WorldGenerator.instance == null)
			{
				return true;
			}
			if (value[0].Biome == value[1].Biome && value[0].Biome == value[2].Biome && value[0].Biome == value[3].Biome)
			{
				return true;
			}
			__result = (Biome)(int)WorldGenerator.instance.GetBiome(point.x, point.z, oceanLevel, waterAlwaysOcean);
			return false;
		}
	}
	[HarmonyPatch(typeof(TerrainComp), "PaintCleared")]
	public static class CompactionBiomeFix
	{
		[ThreadStatic]
		internal static bool ForceDeepNorth;

		private static void Prefix(Vector3 worldPos)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			WorldGenerator instance = WorldGenerator.instance;
			ForceDeepNorth = instance != null && (int)instance.GetBiome(worldPos.x, worldPos.z, 0.02f, false) == 64;
		}

		private static void Finalizer()
		{
			ForceDeepNorth = false;
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "IsDeepnorth")]
	public static class IsDeepNorthOverride
	{
		private static void Postfix(ref bool __result)
		{
			if (CompactionBiomeFix.ForceDeepNorth)
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	public static class RegisterCommands
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ConsoleEvent <0>__Run;

			public static ConsoleEvent <1>__Run;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			internal void <Postfix>b__0_0(ConsoleEventArgs args)
			{
				if (args.Length < 2)
				{
					args.Context.AddString(string.Format("snowshader is {0}, loaded={1}", Plugin.UseShader ? "on" : "off", (Object)(object)Plugin.PatchedShader != (Object)null));
					return;
				}
				Plugin.UseShader = args[1] == "on";
				Heightmap[] array = Object.FindObjectsOfType<Heightmap>();
				for (int i = 0; i < array.Length; i++)
				{
					Plugin.Apply(array[i], Plugin.UseShader);
				}
				args.Context.AddString("snowshader " + (Plugin.UseShader ? "on" : "off"));
			}
		}

		private static void Postfix()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			object obj = <>O.<0>__Run;
			if (obj == null)
			{
				ConsoleEvent val = SnowCheck.Run;
				<>O.<0>__Run = val;
				obj = (object)val;
			}
			new ConsoleCommand("snowcheck", "Prints snow mask / biome info at the player position", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj2 = <>c.<>9__0_0;
			if (obj2 == null)
			{
				ConsoleEvent val2 = delegate(ConsoleEventArgs args)
				{
					if (args.Length < 2)
					{
						args.Context.AddString(string.Format("snowshader is {0}, loaded={1}", Plugin.UseShader ? "on" : "off", (Object)(object)Plugin.PatchedShader != (Object)null));
					}
					else
					{
						Plugin.UseShader = args[1] == "on";
						Heightmap[] array = Object.FindObjectsOfType<Heightmap>();
						for (int i = 0; i < array.Length; i++)
						{
							Plugin.Apply(array[i], Plugin.UseShader);
						}
						args.Context.AddString("snowshader " + (Plugin.UseShader ? "on" : "off"));
					}
				};
				<>c.<>9__0_0 = val2;
				obj2 = (object)val2;
			}
			new ConsoleCommand("snowshader", "snowshader on|off - use the patched terrain shader (Deep North look everywhere)", (ConsoleEvent)obj2, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj3 = <>O.<1>__Run;
			if (obj3 == null)
			{
				ConsoleEvent val3 = SnowTest.Run;
				<>O.<1>__Run = val3;
				obj3 = (object)val3;
			}
			new ConsoleCommand("snowtest", "snowtest vc|mask r g b a (0-1) - overwrite vertex colours or paint mask of the current zone", (ConsoleEvent)obj3, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}
	}
	public static class SnowTest
	{
		public static void Run(ConsoleEventArgs args)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			Heightmap val = (((Object)(object)localPlayer != (Object)null) ? Heightmap.FindHeightmap(((Component)localPlayer).transform.position) : null);
			if ((Object)(object)val == (Object)null || args.Length < 6)
			{
				args.Context.AddString("usage: snowtest vc|mask r g b a   (values 0-1, standing in a loaded zone)");
				return;
			}
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(float.Parse(args[2], CultureInfo.InvariantCulture), float.Parse(args[3], CultureInfo.InvariantCulture), float.Parse(args[4], CultureInfo.InvariantCulture), float.Parse(args[5], CultureInfo.InvariantCulture));
			if (args[1] == "vc")
			{
				Mesh value = Traverse.Create((object)val).Field("m_renderMesh").GetValue<Mesh>();
				Color32[] array = (Color32[])(object)new Color32[value.vertexCount];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = Color32.op_Implicit(val2);
				}
				value.colors32 = array;
			}
			else if (args[1] == "mask")
			{
				Texture2D paintMask = val.GetPaintMask();
				Color[] array2 = (Color[])(object)new Color[((Texture)paintMask).width * ((Texture)paintMask).height];
				for (int j = 0; j < array2.Length; j++)
				{
					array2[j] = val2;
				}
				paintMask.SetPixels(array2);
				paintMask.Apply();
			}
			args.Context.AddString($"snowtest: set {args[1]} of current zone to {val2}");
		}
	}
	public static class SnowCheck
	{
		public static void Run(ConsoleEventArgs args)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || WorldGenerator.instance == null)
			{
				args.Context.AddString("snowcheck: no player or world");
				return;
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			WorldGenerator instance = WorldGenerator.instance;
			Heightmap val = Heightmap.FindHeightmap(position);
			object arg = position.x;
			object arg2 = position.z;
			Vector2 val2 = new Vector2(position.x, position.z);
			Print(args, $"pos x={arg:0} z={arg2:0}  dist from center={((Vector2)(ref val2)).magnitude:0}");
			Print(args, $"vanilla IsDeepnorth: {WorldGenerator.IsDeepnorth(position.x, position.z)}");
			Print(args, $"WorldGenerator.GetBiome (patched): {instance.GetBiome(position.x, position.z, 0.02f, false)}");
			Print(args, $"GetBiomeSector biome: {instance.GetBiomeSector(position, false).Biome}");
			Print(args, $"Heightmap.FindBiome: {Heightmap.FindBiome(position)}");
			Print(args, $"vertex colour for DeepNorth: {Heightmap.GetBiomeColor((Biome)64)}");
			Color val3 = default(Color);
			instance.GetBiomeHeight((Biome)64, position.x, position.z, ref val3, false, true);
			Print(args, $"generated DeepNorth mask here: {val3}");
			if ((Object)(object)val == (Object)null)
			{
				Print(args, "no heightmap found at position");
				return;
			}
			int num = default(int);
			int num2 = default(int);
			val.WorldToVertexMask(position, ref num, ref num2);
			Texture2D paintMask = val.GetPaintMask();
			Print(args, $"live paint mask pixel ({num},{num2}): {paintMask.GetPixel(num, num2)}  (g = snow depth)");
			Print(args, $"GetCultivationMask(g): {val.GetCultivationMask(position):0.00}");
			int num3 = num2 * (val.m_width + 1) + num;
			HMBuildData value = Traverse.Create((object)val).Field("m_buildData").GetValue<HMBuildData>();
			if (value?.m_baseMask != null && num3 >= 0 && num3 < value.m_baseMask.Length)
			{
				Print(args, $"base (pre-modifier) mask pixel: {value.m_baseMask[num3]}");
			}
			TerrainComp val4 = TerrainComp.FindTerrainCompiler(position);
			if ((Object)(object)val4 == (Object)null)
			{
				Print(args, "no TerrainComp at this zone");
			}
			else
			{
				bool[] value2 = Traverse.Create((object)val4).Field("m_modifiedPaint").GetValue<bool[]>();
				Color[] value3 = Traverse.Create((object)val4).Field("m_paintMask").GetValue<Color[]>();
				Print(args, string.Format("TerrainComp modifiedPaint={0} paint={1}", value2 != null && value2[num3], (value3 != null) ? ((object)Unsafe.As<Color, Color>(ref value3[num3])/*cast due to .constrained prefix*/).ToString() : "n/a"));
			}
			Vector3 val5 = default(Vector3);
			int num4 = default(int);
			int num5 = default(int);
			for (int i = -24; i <= 24; i += 6)
			{
				((Vector3)(ref val5))..ctor(position.x, position.y, position.z + (float)i);
				Heightmap val6 = Heightmap.FindHeightmap(val5);
				if ((Object)(object)val6 == (Object)null)
				{
					continue;
				}
				Mesh value4 = Traverse.Create((object)val6).Field("m_renderMesh").GetValue<Mesh>();
				string text = "n/a";
				if ((Object)(object)value4 != (Object)null)
				{
					val6.WorldToVertexMask(val5, ref num4, ref num5);
					Color32[] colors = value4.colors32;
					int num6 = num5 * (val6.m_width + 1) + num4;
					if (num6 >= 0 && num6 < colors.Length)
					{
						text = ((object)Unsafe.As<Color32, Color32>(ref colors[num6])/*cast due to .constrained prefix*/).ToString();
					}
				}
				Print(args, string.Format("dz={0,3} z={1:0} vanillaDN={2} liveG={3:0.00} meshVertexColor={4} height={5:0.0}", i, val5.z, WorldGenerator.IsDeepnorth(val5.x, val5.z) ? "*" : " ", val6.GetCultivationMask(val5), text, val6.GetHeight(px(val6, val5), py(val6, val5))));
			}
			DumpMaterial(args, val);
		}

		private static int px(Heightmap h, Vector3 p)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			int result = default(int);
			int num = default(int);
			h.WorldToVertexMask(p, ref result, ref num);
			return result;
		}

		private static int py(Heightmap h, Vector3 p)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			int num = default(int);
			int result = default(int);
			h.WorldToVertexMask(p, ref num, ref result);
			return result;
		}

		private static void DumpMaterial(ConsoleEventArgs args, Heightmap hm)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected I4, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			Material value = Traverse.Create((object)hm).Field("m_materialInstance").GetValue<Material>();
			if ((Object)(object)value == (Object)null)
			{
				Print(args, "no material instance");
				return;
			}
			Shader shader = value.shader;
			Print(args, string.Format("shader={0} keywords={1} renderers={2}", ((Object)shader).name, string.Join(",", value.shaderKeywords), (Object)(object)((Component)hm).GetComponent<MeshRenderer>() != (Object)null));
			for (int i = 0; i < shader.GetPropertyCount(); i++)
			{
				string propertyName = shader.GetPropertyName(i);
				ShaderPropertyType propertyType = shader.GetPropertyType(i);
				switch ((int)propertyType)
				{
				case 2:
				case 3:
					Print(args, $"  {propertyName} = {value.GetFloat(propertyName)}");
					break;
				case 0:
				case 1:
					Print(args, $"  {propertyName} = {value.GetVector(propertyName)}");
					break;
				case 4:
				{
					Texture texture = value.GetTexture(propertyName);
					Print(args, "  " + propertyName + " = " + (((Object)(object)texture != (Object)null) ? ((Object)texture).name : "null"));
					break;
				}
				}
			}
		}

		private static void Print(ConsoleEventArgs args, string text)
		{
			args.Context.AddString(text);
			Debug.Log((object)("[snowcheck] " + text));
		}
	}
}