Decompiled source of ChromaFlayer v1.0.0

plugin/ChromaFlayer.dll

Decompiled a day ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using ChromaFlayer.Resources;
using HarmonyLib;
using KaimiraGames;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ChromaFlayer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Gives Mindflayers random colors")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ChromaFlayer")]
[assembly: AssemblyTitle("ChromaFlayer")]
[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 KaimiraGames
{
	public class WeightedList<T> : IEnumerable<T>, IEnumerable
	{
		private readonly List<T> _list = new List<T>();

		private readonly List<int> _weights = new List<int>();

		private readonly List<int> _probabilities = new List<int>();

		private readonly List<int> _alias = new List<int>();

		private readonly Random _rand;

		private int _totalWeight;

		private bool _areAllProbabilitiesIdentical;

		private int _minWeight;

		private int _maxWeight;

		public WeightErrorHandlingType BadWeightErrorHandling { get; set; }

		public int TotalWeight => _totalWeight;

		public int MinWeight => _minWeight;

		public int MaxWeight => _maxWeight;

		public IReadOnlyList<T> Items => _list.AsReadOnly();

		public T this[int index] => _list[index];

		public int Count => _list.Count;

		public WeightedList(Random? rand = null)
		{
			_rand = rand ?? new Random();
		}

		public WeightedList(ICollection<WeightedListItem<T>> listItems, Random? rand = null)
		{
			_rand = rand ?? new Random();
			foreach (WeightedListItem<T> listItem in listItems)
			{
				_list.Add(listItem._item);
				_weights.Add(listItem._weight);
			}
			Recalculate();
		}

		public T? Next()
		{
			if (Count == 0)
			{
				return default(T);
			}
			int index = _rand.Next(Count);
			if (_areAllProbabilitiesIdentical)
			{
				return _list[index];
			}
			if (_rand.Next(_totalWeight) >= _probabilities[index])
			{
				return _list[_alias[index]];
			}
			return _list[index];
		}

		public void AddWeightToAll(int weight)
		{
			if (weight + _minWeight <= 0 && BadWeightErrorHandling == WeightErrorHandlingType.ThrowExceptionOnAdd)
			{
				throw new ArgumentException($"Subtracting {-1 * weight} from all items would set weight to non-positive for at least one element.");
			}
			for (int i = 0; i < Count; i++)
			{
				_weights[i] = FixWeight(_weights[i] + weight);
			}
			Recalculate();
		}

		public void SubtractWeightFromAll(int weight)
		{
			AddWeightToAll(weight * -1);
		}

		public void SetWeightOfAll(int weight)
		{
			if (weight <= 0 && BadWeightErrorHandling == WeightErrorHandlingType.ThrowExceptionOnAdd)
			{
				throw new ArgumentException("Weight cannot be non-positive.");
			}
			for (int i = 0; i < Count; i++)
			{
				_weights[i] = FixWeight(weight);
			}
			Recalculate();
		}

		public IEnumerator<T> GetEnumerator()
		{
			return _list.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return _list.GetEnumerator();
		}

		public void Add(T item, int weight)
		{
			_list.Add(item);
			_weights.Add(FixWeight(weight));
			Recalculate();
		}

		public void Add(ICollection<WeightedListItem<T>> listItems)
		{
			foreach (WeightedListItem<T> listItem in listItems)
			{
				_list.Add(listItem._item);
				_weights.Add(FixWeight(listItem._weight));
			}
			Recalculate();
		}

		public void Clear()
		{
			_list.Clear();
			_weights.Clear();
			Recalculate();
		}

		public bool Contains(T item)
		{
			return _list.Contains(item);
		}

		public int IndexOf(T item)
		{
			return _list.IndexOf(item);
		}

		public void Insert(int index, T item, int weight)
		{
			_list.Insert(index, item);
			_weights.Insert(index, FixWeight(weight));
			Recalculate();
		}

		public void Remove(T item)
		{
			int index = IndexOf(item);
			RemoveAt(index);
			Recalculate();
		}

		public void RemoveAt(int index)
		{
			_list.RemoveAt(index);
			_weights.RemoveAt(index);
			Recalculate();
		}

		public void SetWeight(T item, int newWeight)
		{
			SetWeightAtIndex(IndexOf(item), FixWeight(newWeight));
		}

		public int GetWeightOf(T item)
		{
			return GetWeightAtIndex(IndexOf(item));
		}

		public void SetWeightAtIndex(int index, int newWeight)
		{
			_weights[index] = FixWeight(newWeight);
			Recalculate();
		}

		public int GetWeightAtIndex(int index)
		{
			return _weights[index];
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("WeightedList<");
			stringBuilder.Append(typeof(T).Name);
			stringBuilder.Append(">: TotalWeight:");
			stringBuilder.Append(TotalWeight);
			stringBuilder.Append(", Min:");
			stringBuilder.Append(_minWeight);
			stringBuilder.Append(", Max:");
			stringBuilder.Append(_maxWeight);
			stringBuilder.Append(", Count:");
			stringBuilder.Append(Count);
			stringBuilder.Append(", {");
			for (int i = 0; i < _list.Count; i++)
			{
				T val = _list[i];
				stringBuilder.Append((val != null) ? val.ToString() : null);
				stringBuilder.Append(":");
				stringBuilder.Append(_weights[i].ToString());
				if (i < _list.Count - 1)
				{
					stringBuilder.Append(", ");
				}
			}
			stringBuilder.Append("}");
			return stringBuilder.ToString();
		}

		private void Recalculate()
		{
			_totalWeight = 0;
			_areAllProbabilitiesIdentical = false;
			_minWeight = 0;
			_maxWeight = 0;
			bool flag = true;
			_alias.Clear();
			_probabilities.Clear();
			List<int> list = new List<int>(Count);
			List<int> list2 = new List<int>(Count);
			List<int> list3 = new List<int>(Count);
			foreach (int weight in _weights)
			{
				if (flag)
				{
					_minWeight = (_maxWeight = weight);
					flag = false;
				}
				_minWeight = ((weight < _minWeight) ? weight : _minWeight);
				_maxWeight = ((_maxWeight < weight) ? weight : _maxWeight);
				_totalWeight += weight;
				list.Add(weight * Count);
				_alias.Add(0);
				_probabilities.Add(0);
			}
			if (_minWeight == _maxWeight)
			{
				_areAllProbabilitiesIdentical = true;
				return;
			}
			for (int i = 0; i < Count; i++)
			{
				if (list[i] < _totalWeight)
				{
					list2.Add(i);
				}
				else
				{
					list3.Add(i);
				}
			}
			while (list2.Count > 0 && list3.Count > 0)
			{
				int index = list2[list2.Count - 1];
				list2.RemoveAt(list2.Count - 1);
				int num = list3[list3.Count - 1];
				list3.RemoveAt(list3.Count - 1);
				_probabilities[index] = list[index];
				_alias[index] = num;
				int num3 = (list[num] = list[num] + list[index] - _totalWeight);
				if (num3 < _totalWeight)
				{
					list2.Add(num);
				}
				else
				{
					list3.Add(num);
				}
			}
			while (list3.Count > 0)
			{
				int index2 = list3[list3.Count - 1];
				list3.RemoveAt(list3.Count - 1);
				_probabilities[index2] = _totalWeight;
			}
		}

		internal static int FixWeightSetToOne(int weight)
		{
			if (weight > 0)
			{
				return weight;
			}
			return 1;
		}

		internal static int FixWeightExceptionOnAdd(int weight)
		{
			if (weight > 0)
			{
				return weight;
			}
			throw new ArgumentException("Weight cannot be non-positive");
		}

		private int FixWeight(int weight)
		{
			if (BadWeightErrorHandling != WeightErrorHandlingType.ThrowExceptionOnAdd)
			{
				return FixWeightSetToOne(weight);
			}
			return FixWeightExceptionOnAdd(weight);
		}
	}
	public readonly struct WeightedListItem<T>
	{
		internal readonly T _item;

		internal readonly int _weight;

		public WeightedListItem(T item, int weight)
		{
			_item = item;
			_weight = weight;
		}
	}
	public enum WeightErrorHandlingType
	{
		SetWeightToOne,
		ThrowExceptionOnAdd
	}
}
namespace ChromaFlayer
{
	public class ColorUtils
	{
		public static Color HueShiftToColor(Color color, Color target, float amount)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			float num2 = default(float);
			float num3 = default(float);
			float num = default(float);
			Color.RGBToHSV(color, ref num, ref num2, ref num3);
			float num4 = default(float);
			float num5 = default(float);
			float num6 = default(float);
			Color.RGBToHSV(target, ref num4, ref num5, ref num6);
			num = Mathf.Lerp(num, num4, amount);
			return Color.HSVToRGB(num, num2, num3);
		}
	}
	[BepInPlugin("dev.zeddevstuff.chromaflayer", "ChromaFlayer", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private class Palette : IDisposable
		{
			private Texture2D _originalTexture;

			private Dictionary<Color, float> _colors = new Dictionary<Color, float>();

			private WeightedList<KeyValuePair<Texture2D, Color>> _textures = new WeightedList<KeyValuePair<Texture2D, Color>>();

			private List<float> _probabilities = new List<float>();

			public Palette(Texture2D originalTexture)
			{
				_originalTexture = originalTexture;
			}

			public (Texture2D texture, Color color) GetRandomCouple()
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				KeyValuePair<Texture2D, Color> keyValuePair = _textures.Next();
				return (keyValuePair.Key, keyValuePair.Value);
			}

			public Texture2D GetRandom()
			{
				return _textures.Next().Key;
			}

			public void GenerateTextures()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Expected O, but got Unknown
				//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c0: 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_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				foreach (KeyValuePair<Color, float> color in _colors)
				{
					Texture2D val = new Texture2D(((Texture)_originalTexture).width, ((Texture)_originalTexture).height);
					Color? val2 = null;
					for (int i = 0; i < ((Texture)val).width; i++)
					{
						for (int j = 0; j < ((Texture)val).height; j++)
						{
							val.SetPixel(i, j, new Color?(ColorUtils.HueShiftToColor(_originalTexture.GetPixel(i, j), color.Key, 1f)).Value);
						}
					}
					val.Apply();
					_textures.Add(new KeyValuePair<Texture2D, Color>(val, color.Key), (int)(_colors[color.Key] * 100f));
				}
			}

			public static Palette Parse(string data, Texture2D originalTexture)
			{
				//IL_0092: 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_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				Palette palette = new Palette(originalTexture);
				string[] array = data.Split('\n');
				float num = 0f;
				string[] array2 = array;
				Color val = default(Color);
				for (int i = 0; i < array2.Length; i++)
				{
					string[] array3 = array2[i].Split('=');
					if (array3.Length == 2)
					{
						string text = array3[0];
						string[] array4 = array3[1].Split('/');
						if (array4.Length == 2 && float.TryParse(array4[0], out var result) && float.TryParse(array4[1], out var result2))
						{
							float num2 = result / result2;
							num += num2;
							palette._probabilities.Add(num2);
							Color key = (ColorUtility.TryParseHtmlString(text, ref val) ? val : Color.white);
							palette._colors.TryAdd(key, num2);
						}
					}
				}
				palette._colors = palette._colors.OrderByDescending((KeyValuePair<Color, float> x) => x.Value).ToDictionary((KeyValuePair<Color, float> x) => x.Key, (KeyValuePair<Color, float> x) => x.Value);
				return palette;
			}

			public void Dispose()
			{
				foreach (KeyValuePair<Texture2D, Color> texture in _textures)
				{
					Object.Destroy((Object)(object)texture.Key);
				}
			}
		}

		private class Patches
		{
			[HarmonyPatch(typeof(Mindflayer), "Awake")]
			[HarmonyPostfix]
			public static void Mindflayer_Awake(Mindflayer __instance)
			{
				SkinnedMeshRenderer componentInChildren = ((Component)__instance).GetComponentInChildren<SkinnedMeshRenderer>();
				if (!((Object)(object)componentInChildren != (Object)null))
				{
					return;
				}
				string name = ((Object)((Renderer)componentInChildren).material.mainTexture).name;
				if (!(name == "T-MindFlayer"))
				{
					if (name == "T-MindFlayer_M")
					{
						(Texture2D texture, Color color) couple2 = _malePalette.GetRandomCouple();
						((Renderer)componentInChildren).material.mainTexture = (Texture)(object)couple2.texture;
						((Component)__instance).GetComponentsInChildren<TrailRenderer>().ToList().ForEach(delegate(TrailRenderer x)
						{
							//IL_0007: Unknown result type (might be due to invalid IL or missing references)
							//IL_0018: Unknown result type (might be due to invalid IL or missing references)
							//IL_001d: Unknown result type (might be due to invalid IL or missing references)
							//IL_002a: Unknown result type (might be due to invalid IL or missing references)
							x.startColor = couple2.color;
							Color item4 = couple2.color;
							item4.a = 0f;
							x.endColor = item4;
						});
						((Component)__instance).GetComponentsInChildren<LineRenderer>().ToList().ForEach(delegate(LineRenderer x)
						{
							//IL_0007: Unknown result type (might be due to invalid IL or missing references)
							//IL_0018: Unknown result type (might be due to invalid IL or missing references)
							//IL_001d: Unknown result type (might be due to invalid IL or missing references)
							//IL_002a: Unknown result type (might be due to invalid IL or missing references)
							x.startColor = couple2.color;
							Color item3 = couple2.color;
							item3.a = 0f;
							x.endColor = item3;
						});
						((Component)__instance).GetComponentsInChildren<Light>().ToList().ForEach(delegate(Light x)
						{
							//IL_0007: Unknown result type (might be due to invalid IL or missing references)
							x.color = couple2.color;
						});
					}
				}
				else
				{
					(Texture2D texture, Color color) couple = _femalePalette.GetRandomCouple();
					((Renderer)componentInChildren).material.mainTexture = (Texture)(object)couple.texture;
					((Component)__instance).GetComponentsInChildren<TrailRenderer>().ToList().ForEach(delegate(TrailRenderer x)
					{
						//IL_0007: Unknown result type (might be due to invalid IL or missing references)
						//IL_0018: Unknown result type (might be due to invalid IL or missing references)
						//IL_001d: Unknown result type (might be due to invalid IL or missing references)
						//IL_002a: Unknown result type (might be due to invalid IL or missing references)
						x.startColor = couple.color;
						Color item2 = couple.color;
						item2.a = 0f;
						x.endColor = item2;
					});
					((Component)__instance).GetComponentsInChildren<LineRenderer>().ToList().ForEach(delegate(LineRenderer x)
					{
						//IL_0007: Unknown result type (might be due to invalid IL or missing references)
						//IL_0018: Unknown result type (might be due to invalid IL or missing references)
						//IL_001d: Unknown result type (might be due to invalid IL or missing references)
						//IL_002a: Unknown result type (might be due to invalid IL or missing references)
						x.startColor = couple.color;
						Color item = couple.color;
						item.a = 0f;
						x.endColor = item;
					});
					((Component)__instance).GetComponentsInChildren<Light>().ToList().ForEach(delegate(Light x)
					{
						//IL_0007: Unknown result type (might be due to invalid IL or missing references)
						x.color = couple.color;
					});
				}
			}
		}

		private Harmony _patch = new Harmony("dev.zeddevstuff.chromaflayer");

		private static Texture2D? _t_MindFlayer;

		private static Texture2D? _t_MindFlayer_M;

		private static Palette? _malePalette;

		private static Palette? _femalePalette;

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			_patch.PatchAll(typeof(Patches));
			_t_MindFlayer = new Texture2D(128, 128);
			ImageConversion.LoadImage(_t_MindFlayer, AppResources.T_MindFlayer);
			_t_MindFlayer_M = new Texture2D(128, 128);
			ImageConversion.LoadImage(_t_MindFlayer_M, AppResources.T_MindFlayer_M);
			LoadPalettes();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin ChromaFlayer is loaded!");
		}

		private void LoadPalettes()
		{
			DirectoryInfo directoryInfo = new DirectoryInfo(typeof(Mindflayer).Assembly.Location).Parent?.Parent?.Parent;
			if (directoryInfo != null)
			{
				FileInfo fileInfo = directoryInfo.GetFiles("palette.chromaflayer", SearchOption.AllDirectories).FirstOrDefault();
				FileInfo fileInfo2 = directoryInfo.GetFiles("malePalette.chromaflayer", SearchOption.AllDirectories).FirstOrDefault();
				FileInfo fileInfo3 = directoryInfo.GetFiles("femalePalette.chromaflayer", SearchOption.AllDirectories).FirstOrDefault();
				if (fileInfo2 != null)
				{
					_malePalette = Palette.Parse(File.ReadAllText(fileInfo2.FullName), _t_MindFlayer_M);
					_malePalette.GenerateTextures();
				}
				if (fileInfo3 != null)
				{
					_femalePalette = Palette.Parse(File.ReadAllText(fileInfo3.FullName), _t_MindFlayer);
					_femalePalette.GenerateTextures();
				}
				if (fileInfo != null && _malePalette == null)
				{
					_malePalette = Palette.Parse(File.ReadAllText(fileInfo.FullName), _t_MindFlayer_M);
					_malePalette.GenerateTextures();
				}
				if (fileInfo != null && _femalePalette == null)
				{
					_femalePalette = Palette.Parse(File.ReadAllText(fileInfo.FullName), _t_MindFlayer);
					_femalePalette.GenerateTextures();
				}
				if (fileInfo == null && fileInfo2 == null)
				{
					_malePalette = Palette.Parse(Encoding.UTF8.GetString(AppResources.Palette), _t_MindFlayer_M);
					_malePalette.GenerateTextures();
				}
				if (fileInfo == null && fileInfo3 == null)
				{
					_femalePalette = Palette.Parse(Encoding.UTF8.GetString(AppResources.Palette), _t_MindFlayer);
					_femalePalette.GenerateTextures();
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ChromaFlayer";

		public const string PLUGIN_NAME = "ChromaFlayer";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace ChromaFlayer.Resources
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class AppResources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("ChromaFlayer.Resources.AppResources", typeof(AppResources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] Palette => (byte[])ResourceManager.GetObject("Palette", resourceCulture);

		internal static byte[] T_MindFlayer => (byte[])ResourceManager.GetObject("T-MindFlayer", resourceCulture);

		internal static byte[] T_MindFlayer_M => (byte[])ResourceManager.GetObject("T-MindFlayer_M", resourceCulture);

		internal AppResources()
		{
		}
	}
}