Decompiled source of RtDBrightener v1.0.9

plugins/RtDBrightener.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: IgnoresAccessChecksTo("Accessibility")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("assembly_googleanalytics")]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_lux")]
[assembly: IgnoresAccessChecksTo("assembly_postprocessing")]
[assembly: IgnoresAccessChecksTo("assembly_simplemeshcombine")]
[assembly: IgnoresAccessChecksTo("assembly_steamworks")]
[assembly: IgnoresAccessChecksTo("assembly_sunshafts")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: IgnoresAccessChecksTo("com.rlabrecque.steamworks.net")]
[assembly: IgnoresAccessChecksTo("ConnectedStorage")]
[assembly: IgnoresAccessChecksTo("Fishlabs.Common")]
[assembly: IgnoresAccessChecksTo("Fishlabs.Core")]
[assembly: IgnoresAccessChecksTo("Mono.Posix")]
[assembly: IgnoresAccessChecksTo("Mono.WebBrowser")]
[assembly: IgnoresAccessChecksTo("netstandard")]
[assembly: IgnoresAccessChecksTo("PlayFab")]
[assembly: IgnoresAccessChecksTo("PlayFabParty")]
[assembly: IgnoresAccessChecksTo("ui_lib")]
[assembly: IgnoresAccessChecksTo("XblPCSandbox")]
[assembly: IgnoresAccessChecksTo("XGamingRuntime")]
[assembly: AssemblyCompany("RtDBrightener")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.9.0")]
[assembly: AssemblyInformationalVersion("1.0.9+5dcae63ec13076e9f03446102f2c2938423e9d2f")]
[assembly: AssemblyProduct("RtDBrightener")]
[assembly: AssemblyTitle("RtDBrightener")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.9.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 RtDBrightener
{
	[BepInPlugin("ashr4f.rtdbrightener", "RtDBrightener", "1.0.9")]
	public class RtDBrightenerPlugin : BaseUnityPlugin
	{
		public const string ModGuid = "ashr4f.rtdbrightener";

		public const string ModName = "RtDBrightener";

		public const string ModVersion = "1.0.9";

		internal static ManualLogSource Log = null;

		private static ConfigEntry<bool> _enabled = null;

		private static ConfigEntry<float> _brightness = null;

		private static ConfigEntry<float> _saturation = null;

		private static ConfigEntry<float> _iconSaturation = null;

		private static ConfigEntry<float> _iconContrast = null;

		private static ConfigEntry<float> _iconBrightness = null;

		private static ConfigEntry<string> _iconExceptions = null;

		private static ConfigEntry<string> _nameContains = null;

		private static ConfigEntry<bool> _brightenPlants = null;

		private static ConfigEntry<bool> _brightenIcons = null;

		private static readonly HashSet<Material> _doneMaterials = new HashSet<Material>();

		private static readonly HashSet<string> _doneIcons = new HashSet<string>();

		private static readonly Dictionary<Texture2D, Texture2D> _texCache = new Dictionary<Texture2D, Texture2D>();

		private void Awake()
		{
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch.");
			_brightness = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Brightness Gamma", 0.55f, "Gamma curve applied to 3D materials. 1 = unchanged, lower = brighter shadows. 0.55 lifts dark assets a lot, 0.8 is subtle.");
			_saturation = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Saturation Multiplier", 1.4f, "Multiplier applied to 3D material color saturation. 1 = unchanged.");
			_iconSaturation = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Icon Saturation Boost", 2.2f, "Extra color boost for inventory and map icons. 1 = unchanged, higher = more colorful. Applied as a curve, mid colors gain the most.");
			_iconContrast = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Icon Contrast", 0.2f, "S curve strength for icons, restores depth after the gamma lift. 0 = flat, 0.2 = balanced, 0.5 = punchy.");
			_iconBrightness = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Icon Brightness Gamma", 0.45f, "Gamma curve for icons only. Lower = brighter. Icons need a stronger lift than 3D models since they get no scene lighting.");
			_iconExceptions = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Icon Exceptions", "Rice:0.5", "Comma-separated Name:Weight pairs. Weight scales the whole icon effect for matching items. 0 = untouched, 0.5 = half effect, 1 = full. Example: Rice:0.5");
			_nameContains = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Name Contains", "Vegetable_*RtD, Pickable_*RtD, Sapling_*RtD, Seed*RtD, SeaWeed", "Comma-separated name fragments. World prefabs whose name contains one of these are brightened, along with the items they drop.\nA * means the name must contain the left part followed by the right part, so Vegetable_*RtD targets crops without touching animals.");
			_brightenPlants = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Brighten World Objects", true, "Brighten the 3D materials of matching prefabs (plants, pickables).");
			_brightenIcons = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Brighten Icons", true, "Brighten the inventory icons of matching items.");
			new Harmony("ashr4f.rtdbrightener").PatchAll();
		}

		private static float ExceptionWeight(string itemName)
		{
			string[] array = _iconExceptions.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { ':' });
				if (array2.Length == 2 && itemName.IndexOf(array2[0].Trim(), StringComparison.OrdinalIgnoreCase) >= 0 && float.TryParse(array2[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					return Mathf.Clamp01(result);
				}
			}
			return 1f;
		}

		internal static bool NameMatches(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			string[] array = _nameContains.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length == 0)
				{
					continue;
				}
				int num = text.IndexOf('*');
				if (num >= 0)
				{
					string text2 = text.Substring(0, num).Trim();
					string text3 = text.Substring(num + 1).Trim();
					if (text2.Length != 0 && text3.Length != 0)
					{
						int num2 = name.IndexOf(text2, StringComparison.OrdinalIgnoreCase);
						if (num2 >= 0 && name.IndexOf(text3, num2 + text2.Length, StringComparison.OrdinalIgnoreCase) >= 0)
						{
							return true;
						}
					}
				}
				else if (name.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			return false;
		}

		private static Color Adjust(Color c, bool icon)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num3 = default(float);
			float num2 = default(float);
			Color.RGBToHSV(c, ref num, ref num2, ref num3);
			float num4 = (icon ? _iconBrightness.Value : _brightness.Value);
			float num5 = Mathf.Clamp01(num3);
			num3 = Mathf.Clamp01(Mathf.Pow(num5, Mathf.Max(0.1f, num4)));
			if (icon)
			{
				float num6 = Mathf.Clamp01(_iconContrast.Value);
				num3 = Mathf.Lerp(num3, num3 * num3 * (3f - 2f * num3), num6);
				float num7 = Mathf.Min(2.2f, Mathf.Pow(num3 / Mathf.Max(num5, 0.05f), 0.7f));
				float num8 = Mathf.Max(1f, _iconSaturation.Value);
				float num9 = Mathf.Clamp01(Mathf.Pow(Mathf.Clamp01(num2), 1f / num8));
				num2 = Mathf.Clamp01(Mathf.Lerp(num2, num9, Mathf.SmoothStep(0f, 1f, num3)) * Mathf.Max(1f, num7));
				if (num2 > 0.8f)
				{
					float num10 = (num2 - 0.8f) / 0.2f;
					num2 = 0.8f + 0.2f * (num10 / (1f + 0.25f * num10));
				}
			}
			else
			{
				num2 = Mathf.Clamp01(num2 * _saturation.Value);
			}
			Color result = Color.HSVToRGB(num, num2, num3);
			result.a = c.a;
			return result;
		}

		private static List<GameObject> FindItemCandidates()
		{
			List<GameObject> list = new List<GameObject>();
			if ((Object)(object)ObjectDB.instance != (Object)null)
			{
				foreach (GameObject item in ObjectDB.instance.m_items)
				{
					if ((Object)(object)item != (Object)null && NameMatches(((Object)item).name))
					{
						list.Add(item);
					}
				}
			}
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					if (!((Object)(object)prefab == (Object)null) && NameMatches(((Object)prefab).name))
					{
						Pickable component = prefab.GetComponent<Pickable>();
						if ((Object)(object)component != (Object)null && (Object)(object)component.m_itemPrefab != (Object)null)
						{
							list.Add(component.m_itemPrefab);
						}
						if ((Object)(object)prefab.GetComponent<ItemDrop>() != (Object)null)
						{
							list.Add(prefab);
						}
					}
				}
			}
			return list;
		}

		internal static void BrightenIcons(string phase)
		{
			if (!_enabled.Value || !_brightenIcons.Value)
			{
				return;
			}
			int num = 0;
			List<string> list = new List<string>();
			foreach (GameObject item in FindItemCandidates())
			{
				if ((Object)(object)item == (Object)null || _doneIcons.Contains(((Object)item).name))
				{
					continue;
				}
				ItemDrop component = item.GetComponent<ItemDrop>();
				if ((Object)(object)component == (Object)null || component.m_itemData.m_shared.m_icons == null)
				{
					continue;
				}
				_doneIcons.Add(((Object)item).name);
				float num2 = ExceptionWeight(((Object)item).name);
				if (num2 <= 0f)
				{
					continue;
				}
				int num3 = num;
				Sprite[] icons = component.m_itemData.m_shared.m_icons;
				for (int i = 0; i < icons.Length; i++)
				{
					Sprite val = BrightenSprite(icons[i], num2);
					if ((Object)(object)val != (Object)null)
					{
						icons[i] = val;
						num++;
					}
				}
				if (num > num3)
				{
					list.Add(((Object)item).name);
				}
				int mats = 0;
				BrightenRenderers(item, ref mats);
			}
			if (num > 0)
			{
				Log.LogInfo((object)string.Format("{0} [{1}]: brightened {2} icons on: {3}", "RtDBrightener", phase, num, string.Join(", ", list.ToArray())));
			}
			else if (phase == "ZNetScene" && _doneIcons.Count == 0)
			{
				Log.LogWarning((object)"RtDBrightener: no item matched. Check the Name Contains filter.");
			}
		}

		private static void BrightenRenderers(GameObject root, ref int mats)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Material[] sharedMaterials = componentsInChildren[i].sharedMaterials;
				foreach (Material val in sharedMaterials)
				{
					if ((Object)(object)val == (Object)null || _doneMaterials.Contains(val))
					{
						continue;
					}
					_doneMaterials.Add(val);
					bool flag = false;
					if (val.HasProperty("_Color"))
					{
						val.SetColor("_Color", Adjust(val.GetColor("_Color"), icon: false));
						flag = true;
					}
					if (val.HasProperty("_MainTex"))
					{
						Texture texture = val.GetTexture("_MainTex");
						Texture2D val2 = BrightenTexture((Texture2D)(object)((texture is Texture2D) ? texture : null));
						if ((Object)(object)val2 != (Object)null)
						{
							val.SetTexture("_MainTex", (Texture)(object)val2);
							flag = true;
						}
					}
					if (flag)
					{
						mats++;
					}
				}
			}
		}

		internal static void BrightenAll()
		{
			if (!_enabled.Value)
			{
				return;
			}
			int mats = 0;
			if (_brightenPlants.Value && (Object)(object)ZNetScene.instance != (Object)null)
			{
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					if (!((Object)(object)prefab == (Object)null) && NameMatches(((Object)prefab).name))
					{
						BrightenRenderers(prefab, ref mats);
					}
				}
			}
			BrightenIcons("ZNetScene");
			Log.LogInfo((object)string.Format("{0}: adjusted {1} materials.", "RtDBrightener", mats));
		}

		private static Texture2D? BrightenTexture(Texture2D src)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)src == (Object)null || ((Texture)src).width > 4096 || ((Texture)src).height > 4096)
			{
				return null;
			}
			if (_texCache.TryGetValue(src, out Texture2D value))
			{
				return value;
			}
			try
			{
				RenderTexture temporary = RenderTexture.GetTemporary(((Texture)src).width, ((Texture)src).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
				Graphics.Blit((Texture)(object)src, temporary);
				RenderTexture active = RenderTexture.active;
				RenderTexture.active = temporary;
				Texture2D val = new Texture2D(((Texture)src).width, ((Texture)src).height, (TextureFormat)4, true);
				val.ReadPixels(new Rect(0f, 0f, (float)((Texture)src).width, (float)((Texture)src).height), 0, 0);
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
				Color[] pixels = val.GetPixels();
				for (int i = 0; i < pixels.Length; i++)
				{
					pixels[i] = Adjust(pixels[i], icon: false);
				}
				val.SetPixels(pixels);
				val.Apply(true);
				((Object)val).name = ((Object)src).name + "_bright";
				_texCache[src] = val;
				return val;
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("RtDBrightener: texture " + ((Object)src).name + " skipped (" + ex.Message + ")"));
				_texCache[src] = null;
				return null;
			}
		}

		private static Sprite? BrightenSprite(Sprite sprite, float weight)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0069: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sprite == (Object)null)
			{
				return null;
			}
			try
			{
				Rect rect = sprite.rect;
				int num = (int)((Rect)(ref rect)).width;
				rect = sprite.rect;
				int num2 = (int)((Rect)(ref rect)).height;
				Texture2D texture = sprite.texture;
				RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
				Graphics.Blit((Texture)(object)texture, temporary);
				RenderTexture active = RenderTexture.active;
				RenderTexture.active = temporary;
				Texture2D val = new Texture2D(num, num2, (TextureFormat)4, true);
				((Texture)val).wrapMode = (TextureWrapMode)1;
				rect = sprite.rect;
				float x = ((Rect)(ref rect)).x;
				float num3 = ((Texture)texture).height;
				rect = sprite.rect;
				val.ReadPixels(new Rect(x, num3 - ((Rect)(ref rect)).y - (float)num2, (float)num, (float)num2), 0, 0);
				val.Apply();
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
				Color[] pixels = val.GetPixels(0);
				for (int i = 0; i < pixels.Length; i++)
				{
					if (!(pixels[i].a < 0.02f))
					{
						pixels[i] = Color.Lerp(pixels[i], Adjust(pixels[i], icon: true), weight);
					}
				}
				val.SetPixels(pixels, 0);
				val.Apply(true);
				return Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num2), new Vector2(0.5f, 0.5f), sprite.pixelsPerUnit);
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("RtDBrightener: icon " + ((Object)sprite).name + " skipped (" + ex.Message + ")"));
				return null;
			}
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	internal static class ObjectDB_Awake_Patch
	{
		[HarmonyPriority(0)]
		private static void Postfix()
		{
			RtDBrightenerPlugin.BrightenIcons("ObjectDB");
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class ZNetScene_Awake_Patch
	{
		[HarmonyPriority(0)]
		private static void Postfix()
		{
			RtDBrightenerPlugin.BrightenAll();
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}