Decompiled source of DefibroFaceExpressions v1.1.0

plugins/DefibroFaceExpressions/DefibroFaceExpressions.dll

Decompiled 13 hours ago
using System;
using System.Diagnostics;
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 UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("DefibroFaceExpressions")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DefibroFaceExpressions")]
[assembly: AssemblyTitle("DefibroFaceExpressions")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace DFE
{
	public static class Constants
	{
		public static class AssetPaths
		{
			public static string AssemblyPath => Assembly.GetExecutingAssembly().Location;

			public static string AssemblyFolder => Path.GetDirectoryName(AssemblyPath);

			public static string NewExpressionPath => Path.Join((ReadOnlySpan<char>)Plugin.Instance.ConfigExpressionPath.Value, (ReadOnlySpan<char>)("/" + Plugin.Instance.ConfigExpressionFileName.Value));
		}
	}
	[BepInPlugin("com.averyocean65.defibrofaceexpressions", "DefibroFaceExpressions", "1.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		private class PluginInfo
		{
			public const string GUID = "com.averyocean65.defibrofaceexpressions";

			public const string Name = "DefibroFaceExpressions";

			public const string Version = "1.1.0";
		}

		public static Plugin Instance;

		public ConfigEntry<bool> ConfigDebugMode;

		public ConfigEntry<bool> ConfigVerboseLogging;

		public ConfigEntry<bool> ConfigCacheTexture;

		public ConfigEntry<string> ConfigExpressionPath;

		public ConfigEntry<string> ConfigExpressionFileName;

		public static ManualLogSource LogSource => ((BaseUnityPlugin)Instance).Logger;

		private void Awake()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)Instance))
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			Instance = this;
			Harmony val = new Harmony("com.averyocean65.defibrofaceexpressions");
			val.PatchAll();
			ConfigCacheTexture = ((BaseUnityPlugin)this).Config.Bind<bool>("Performance", "CacheTexture", true, "Determines whether the texture should be loaded into the game once or re-loaded from disk each time a Defibro spawns.");
			ConfigExpressionPath = ((BaseUnityPlugin)this).Config.Bind<string>("IO", "ExpressionFolderPath", Constants.AssetPaths.AssemblyFolder, "Where the folder for the expression file is on your file system.");
			ConfigExpressionFileName = ((BaseUnityPlugin)this).Config.Bind<string>("IO", "ExpressionFileName", "expressions.png", "The name of the expressions file.");
			ConfigDebugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Developer", "DebugMode", false, "Whether to toggle on the debug mode for DefibroFaceExpressions.");
			ConfigVerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Developer", "VerboseLogging", false, "Enable or disable verbose logging.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Looking for: " + Constants.AssetPaths.NewExpressionPath));
		}
	}
}
namespace DFE.Patches
{
	[HarmonyPatch]
	public class DefibroPatches
	{
		private static Vector2 _lastOffset = new Vector2(10000f, 10000f);

		private static MethodInfo _setFacialExpression;

		private static MethodInfo _updateFaceBounce;

		private static Texture2D _cachedFaceTextureAtlas;

		private static float _lastExprChangeTime = 0f;

		private static float[] _facialExpressions = new float[10] { 0.101f, 0.179f, 0.023f, 0.257f, 0.335f, 0.413f, 0.491f, 0.569f, 0.647f, 0.728f };

		private static int _facialExprIndex = 0;

		public static bool _debugMode => Plugin.Instance.ConfigDebugMode.Value;

		public static bool _logging => Plugin.Instance.ConfigVerboseLogging.Value;

		private static Texture2D FaceTextureAtlas
		{
			get
			{
				if (!Plugin.Instance.ConfigCacheTexture.Value)
				{
					return LoadTexture(Constants.AssetPaths.NewExpressionPath);
				}
				if (!Object.op_Implicit((Object)(object)_cachedFaceTextureAtlas))
				{
					_cachedFaceTextureAtlas = LoadTexture(Constants.AssetPaths.NewExpressionPath);
				}
				return _cachedFaceTextureAtlas;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ItemReviveItem), "Start")]
		private static void PatchStart(ItemReviveItem __instance)
		{
			if (!Object.op_Implicit((Object)(object)FaceTextureAtlas))
			{
				Plugin.LogSource.LogError((object)("No expressions.png found in " + Constants.AssetPaths.NewExpressionPath));
				return;
			}
			((Renderer)__instance.FaceMeshRenderer).material.mainTexture = (Texture)(object)FaceTextureAtlas;
			_setFacialExpression = AccessTools.Method(typeof(ItemReviveItem), "SetFacialExpression", new Type[1] { typeof(float) }, (Type[])null);
			_updateFaceBounce = AccessTools.Method(typeof(ItemReviveItem), "UpdateFaceBounce", (Type[])null, (Type[])null);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemReviveItem), "UpdateFaceBounce")]
		private static void PatchUpdateFaceBounce(ItemReviveItem __instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (_logging)
			{
				Vector2 mainTextureOffset = ((Renderer)__instance.FaceMeshRenderer).material.mainTextureOffset;
				if (!(Mathf.Abs(mainTextureOffset.x - _lastOffset.x) < 0.01f))
				{
					_lastOffset = mainTextureOffset;
					Plugin.LogSource.LogInfo((object)$"Offset: [{mainTextureOffset.x}; {mainTextureOffset.y}]");
				}
			}
		}

		private static void SwitchThroughFacialExpressions(ItemReviveItem instance)
		{
			if (Mathf.Abs(Time.time - _lastExprChangeTime) > 2f)
			{
				_lastExprChangeTime = Time.time;
				_facialExprIndex++;
				if (_facialExprIndex >= _facialExpressions.Length)
				{
					_facialExprIndex = 0;
				}
			}
			_setFacialExpression.Invoke(instance, new object[1] { _facialExpressions[_facialExprIndex] });
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ItemReviveItem), "FacialExpressionLogic")]
		private static bool PatchFacialExpression(ItemReviveItem __instance)
		{
			if (_debugMode)
			{
				SwitchThroughFacialExpressions(__instance);
			}
			return !_debugMode;
		}

		private static Texture2D LoadTexture(string filePath)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			Texture2D val = new Texture2D(256, 32);
			byte[] array = File.ReadAllBytes(filePath);
			ImageConversion.LoadImage(val, array);
			return val;
		}
	}
}