Decompiled source of Loincloth of Shame v1.0.0

LoinclothOfShame.dll

Decompiled 3 hours ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LoinClothofShame")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Hewlett-Packard Company")]
[assembly: AssemblyProduct("LoinClothofShame")]
[assembly: AssemblyCopyright("Copyright © Hewlett-Packard Company 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6e89fbdb-51c5-427a-8b86-a25486abe13a")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = "")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 LoinclothOfShame
{
	[BepInPlugin("com.yourname.loinclothofshame", "Loincloth of Shame", "1.0.0")]
	public class LoinclothOfShamePlugin : BaseUnityPlugin
	{
		public const string GUID = "com.yourname.loinclothofshame";

		public const string MOD_NAME = "Loincloth of Shame";

		public const string VERSION = "1.0.0";

		internal static ManualLogSource? Log;

		internal static readonly Color[] ShameColors = (Color[])(object)new Color[10]
		{
			new Color(1f, 0.4f, 0.7f),
			new Color(0.8f, 0.4f, 1f),
			new Color(1f, 1f, 0.2f),
			new Color(0.2f, 1f, 0.4f),
			new Color(0.2f, 0.8f, 1f),
			new Color(1f, 0.5f, 0.1f),
			new Color(1f, 0.2f, 0.2f),
			new Color(0.9f, 0.9f, 1f),
			new Color(1f, 0.08f, 0.58f),
			new Color(0.5f, 1f, 0.8f)
		};

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			new Harmony("com.yourname.loinclothofshame").PatchAll();
			Log.LogInfo((object)"Loincloth of Shame v1.0.0 loaded — prepare for shame.");
		}
	}
	[HarmonyPatch(typeof(Player), "OnDeath")]
	internal static class Patch_Player_OnDeath
	{
		private static GameObject? _shameHost;

		[HarmonyPostfix]
		private static void Postfix(Player __instance)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			if (((Character)__instance).IsOwner())
			{
				Color[] shameColors = LoinclothOfShamePlugin.ShameColors;
				Color val2 = (ShameState.PendingColor = shameColors[Random.Range(0, shameColors.Length)]);
				ShameState.HasPendingColor = true;
				if ((Object)(object)_shameHost == (Object)null)
				{
					_shameHost = new GameObject("ShameHost");
					Object.DontDestroyOnLoad((Object)(object)_shameHost);
				}
				ShameComponent component = _shameHost.GetComponent<ShameComponent>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
				_shameHost.AddComponent<ShameComponent>();
				ManualLogSource? log = LoinclothOfShamePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("[LoinclothOfShame] Death! Shame colour: #" + ColorUtility.ToHtmlStringRGB(val2)));
				}
			}
		}
	}
	public class ShameComponent : MonoBehaviour
	{
		private void LateUpdate()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!ShameState.HasPendingColor)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				VisEquipment component = ((Component)localPlayer).GetComponent<VisEquipment>();
				if (!((Object)(object)component == (Object)null))
				{
					TextureTinter.ApplyShameColor(component, ShameState.PendingColor);
				}
			}
		}
	}
	internal static class ShameState
	{
		public static bool HasPendingColor { get; set; } = false;


		public static Color PendingColor { get; set; } = Color.white;


		public static bool Applied { get; set; } = false;

	}
	internal static class TextureTinter
	{
		private static Texture2D? _tintedLegs;

		private static Texture2D? _tintedChest;

		private static Color _lastColor = Color.clear;

		private static Texture2D? _originalLegs;

		private static Texture2D? _originalChest;

		private static Texture2D? _maskLegs;

		private static Texture2D? _maskChest;

		private static bool _masksLoadFailed = false;

		private static Texture2D MakeReadable(Texture source)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0);
			Graphics.Blit(source, temporary);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D(source.width, source.height, (TextureFormat)4, false);
			val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			return val;
		}

		private static Texture2D? LoadMask(string filename)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = "LoinclothOfShame.Assets." + filename;
			Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(text);
			if (manifestResourceStream == null)
			{
				ManualLogSource? log = LoinclothOfShamePlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[LoinclothOfShame] Missing embedded resource '" + text + "'"));
				}
				return null;
			}
			using (manifestResourceStream)
			{
				byte[] array = new byte[manifestResourceStream.Length];
				manifestResourceStream.Read(array, 0, array.Length);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				typeof(Texture2D).GetMethod("LoadImage", new Type[1] { typeof(byte[]) })?.Invoke(val, new object[1] { array });
				Texture2D val2 = MakeReadable((Texture)(object)val);
				((Object)val2).name = Path.GetFileNameWithoutExtension(filename);
				Object.Destroy((Object)(object)val);
				ManualLogSource? log2 = LoinclothOfShamePlugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)$"[LoinclothOfShame] Loaded mask '{filename}' ({((Texture)val2).width}x{((Texture)val2).height})");
				}
				return val2;
			}
		}

		private static bool EnsureMasks()
		{
			if (_masksLoadFailed)
			{
				return false;
			}
			if (_maskLegs == null)
			{
				_maskLegs = LoadMask("StartingRagsLegs_d.png");
			}
			if (_maskChest == null)
			{
				_maskChest = LoadMask("StartingRagsChest_d.png");
			}
			if ((Object)(object)_maskLegs == (Object)null || (Object)(object)_maskChest == (Object)null)
			{
				_masksLoadFailed = true;
				return false;
			}
			return true;
		}

		private static void CaptureOriginals(Material mat)
		{
			if ((Object)(object)_originalLegs == (Object)null && mat.HasProperty("_LegsTex"))
			{
				Texture texture = mat.GetTexture("_LegsTex");
				if ((Object)(object)texture != (Object)null && (Object)(object)texture != (Object)(object)_tintedLegs)
				{
					_originalLegs = MakeReadable(texture);
					ManualLogSource? log = LoinclothOfShamePlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)("[LoinclothOfShame] Captured _LegsTex '" + ((Object)texture).name + "'"));
					}
				}
			}
			if (!((Object)(object)_originalChest == (Object)null) || !mat.HasProperty("_ChestTex"))
			{
				return;
			}
			Texture texture2 = mat.GetTexture("_ChestTex");
			string text = ((texture2 == null) ? null : ((Object)texture2).name?.ToLowerInvariant()) ?? "";
			if ((Object)(object)texture2 != (Object)null && (Object)(object)texture2 != (Object)(object)_tintedChest && !text.Contains("armor_none") && !text.Contains("startingrags"))
			{
				_originalChest = MakeReadable(texture2);
				ManualLogSource? log2 = LoinclothOfShamePlugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)("[LoinclothOfShame] Captured _ChestTex '" + ((Object)texture2).name + "'"));
				}
			}
		}

		private static Texture2D Composite(Texture2D original, Texture2D mask, Color tint)
		{
			//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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = mask;
			bool flag = false;
			if (((Texture)mask).width != ((Texture)original).width || ((Texture)mask).height != ((Texture)original).height)
			{
				RenderTexture temporary = RenderTexture.GetTemporary(((Texture)original).width, ((Texture)original).height, 0, (RenderTextureFormat)0);
				Graphics.Blit((Texture)(object)mask, temporary);
				RenderTexture active = RenderTexture.active;
				RenderTexture.active = temporary;
				val = new Texture2D(((Texture)original).width, ((Texture)original).height, (TextureFormat)4, false);
				val.ReadPixels(new Rect(0f, 0f, (float)((Texture)original).width, (float)((Texture)original).height), 0, 0);
				val.Apply();
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
				flag = true;
			}
			Color[] pixels = original.GetPixels();
			Color[] pixels2 = val.GetPixels();
			Color[] array = (Color[])(object)new Color[pixels.Length];
			for (int i = 0; i < pixels.Length; i++)
			{
				float num = pixels2[i].r * 0.299f + pixels2[i].g * 0.587f + pixels2[i].b * 0.114f;
				array[i] = (Color)((num > 0.05f) ? new Color(num * tint.r, num * tint.g, num * tint.b, pixels[i].a) : pixels[i]);
			}
			if (flag)
			{
				Object.Destroy((Object)(object)val);
			}
			Texture2D val2 = new Texture2D(((Texture)original).width, ((Texture)original).height, (TextureFormat)4, false);
			val2.SetPixels(array);
			val2.Apply();
			return val2;
		}

		private static bool EnsureTinted(Color color)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			if (!EnsureMasks())
			{
				return false;
			}
			if ((Object)(object)_originalLegs == (Object)null)
			{
				return false;
			}
			if ((Object)(object)_tintedLegs != (Object)null && _lastColor == color)
			{
				return true;
			}
			if ((Object)(object)_tintedLegs != (Object)null)
			{
				Object.Destroy((Object)(object)_tintedLegs);
			}
			if ((Object)(object)_tintedChest != (Object)null)
			{
				Object.Destroy((Object)(object)_tintedChest);
			}
			_tintedLegs = Composite(_originalLegs, _maskLegs, color);
			_tintedChest = (((Object)(object)_originalChest != (Object)null) ? Composite(_originalChest, _maskChest, color) : null);
			_lastColor = color;
			ManualLogSource? log = LoinclothOfShamePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("[LoinclothOfShame] Applied shame colour #" + ColorUtility.ToHtmlStringRGB(color)));
			}
			return true;
		}

		public static void ApplyShameColor(VisEquipment visEq, Color shameColor)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (!EnsureMasks())
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)visEq).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] materials = val.materials;
				foreach (Material val2 in materials)
				{
					if (!((Object)val2).name.ToLowerInvariant().Contains("playermaterial"))
					{
						continue;
					}
					CaptureOriginals(val2);
					if (!EnsureTinted(shameColor))
					{
						continue;
					}
					if ((Object)(object)_tintedLegs != (Object)null && val2.HasProperty("_LegsTex"))
					{
						val2.SetTexture("_LegsTex", (Texture)(object)_tintedLegs);
					}
					if ((Object)(object)_tintedChest != (Object)null && val2.HasProperty("_ChestTex"))
					{
						Texture texture = val2.GetTexture("_ChestTex");
						string text = ((texture == null) ? null : ((Object)texture).name?.ToLowerInvariant()) ?? "";
						if (!text.Contains("armor_none"))
						{
							val2.SetTexture("_ChestTex", (Texture)(object)_tintedChest);
						}
					}
				}
			}
		}

		public static void RestoreOriginal(VisEquipment visEq)
		{
			Renderer[] componentsInChildren = ((Component)visEq).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] materials = val.materials;
				foreach (Material val2 in materials)
				{
					if (((Object)val2).name.ToLowerInvariant().Contains("playermaterial"))
					{
						if ((Object)(object)_originalLegs != (Object)null && val2.HasProperty("_LegsTex"))
						{
							val2.SetTexture("_LegsTex", (Texture)(object)_originalLegs);
						}
						if ((Object)(object)_originalChest != (Object)null && val2.HasProperty("_ChestTex"))
						{
							val2.SetTexture("_ChestTex", (Texture)(object)_originalChest);
						}
					}
				}
			}
		}
	}
}